모형 선택
모형 선택 (Model Selection)
- 여러 예측 모형 중 어떤 모형이 가장 좋은지 선택하는 과정.
과대적합 (Overfitting)
- 원인: 최소제곱법은 주어진 표본에서 잔차 분산 가장 작게 하는 계수 찾음.
- 문제점: 표본에는 실제 모집단 패턴 외 표집 오차(noise) 포함됨. 표본 데이터에만 지나치게 맞춰진 모형은 새로운 데이터(모집단) 예측 성능 떨어짐.
독립변수 개수와 과적합
- 최소제곱법 특성: 종속변수와 아무 관련 없는 독립변수 추가해도 표본 잔차 분산 거의 항상 작아짐 (우연한 관계 때문).
- 결과: 독립변수 많을수록 표본 데이터 대한 값은 무조건 높아지는 경향. → 과적합 위험 증가.
import numpy as np
np.random.seed(0)
random_data = pd.DataFrame({
'x1': np.random.randn(5), # 모든 변수를 무작위로 생성
'x2': np.random.randn(5),
'x3': np.random.randn(5),
'x4': np.random.randn(5),
'y': np.random.randn(5)
})
# 회귀분석을 하면 R제곱이 100%
ols('y ~ x1 + x2 + x3 + x4', data=random_data).fit().summary()
수정 R제곱, AIC, BIC
- 단점 보완 위해 등장한 모형 비교 지표. 모형 복잡도(독립변수 개수)에 페널티 부여.
- 수정 R제곱 (Adjusted R-squared): 보정. 클수록 좋음.
- AIC (Akaike Information Criterion), BIC (Bayesian Information Criterion): 잔차 분산 보정. 작을수록 좋음.
단계적 회귀분석 (Stepwise Regression)
- 목적: 여러 독립변수 후보 중 예측력 좋은 변수들만 자동 선택하는 기법. (독립변수 조합 2^k개 모두 탐색 불가 시 사용)
- 방식: 독립변수 하나씩 **추가(전진)**하거나 **제거(후진)**하며 모형 성능 변화(통계적 유의성, AIC 등) 평가.
- 장점: 예측력 유의한 변수 조합 빠르게 탐색 가능.
- 단점:
- 데이터 기반 자동 선택이므로 이론적 근거 없는 변수 선택 가능.
- 탐색 경로 따라 최적 조합 놓칠 수 있음.
- 권장: 탐색적 분석 목적으로만 사용. 최종 모형은 이론/선행연구 기반하여 결정해야 함.
전진 선택 (Forward Selection)
- 빈 모형에서 시작.
- 가장 설명력 높이는 변수 1개 추가.
- 기존 변수 포함 상태에서, 설명력 가장 높이는 다음 변수 추가.
- 더 이상 추가해도 설명력 유의하게 향상되지 않으면 중단.
data = df
depvar = 'price'
features = ['year', 'mileage', 'model', 'my_car_damage', 'other_car_damage']
included = []
threshold = 0.01
changed = True
best_formula = depvar + ' ~ 1'
best_model = ols(best_formula, data=data).fit() # 절편만 있는 모형
print(f'{best_formula} (AIC: {best_model.aic})') # 절편만 있는 모형 출력
while changed:
excluded = list(set(features) - set(included)) # 미포함 독립변수
best_feature = None # 후보 독립변수
for new_feature in excluded: # 하나씩 추가함
formula = depvar + ' ~ ' + ' + '.join(included + [new_feature])
model = ols(formula, data=data).fit()
if model.aic < best_model.aic - threshold:
# 모델의 AIC가 최상의 모델보다 역치 이하로 개선되면
best_feature = new_feature # 추가 변수 선정
best_model = model # 최상의 모델을 교체
best_formula = formula # 최상의 공식 업데이트
changed = best_feature is not None
if changed: # 변경이 발생했으면
included.append(best_feature) # 추가
print(f'{best_formula} (AIC: {best_model.aic})')
best_model.summary() # 최종 모형 요약 출력
후진 선택 (Backward Selection)
- 모든 변수 포함 모형에서 시작.
- 설명력 가장 적게 감소시키는 변수 1개 제거.
- 남은 변수 중, 설명력 가장 적게 감소시키는 다음 변수 제거.
- 변수 제거 시 설명력 유의하게 감소하면 중단.
data = df
depvar = 'price'
features = ['year', 'mileage', 'my_car_damage', 'other_car_damage']
included = features.copy()
threshold = 0.01
changed = True
best_formula = depvar + ' ~ ' + ' + '.join(included) # 초기 모형
best_model = ols(best_formula, data=data).fit()
print(f'{best_formula} (AIC: {best_model.aic})') # 초기 모형 출력
while changed:
best_feature = None
for remove_feature in included:
model_features = list(set(included) - set([remove_feature]))
formula = depvar + ' ~ ' + ' + '.join(model_features)
model = ols(formula, data=data).fit()
if model.aic < best_model.aic - threshold:
best_feature = remove_feature
best_model = model
best_formula = formula
changed = best_feature is not None
if changed:
included.remove(best_feature)
print(f'{best_formula} (AIC: {best_model.aic})')
best_model.summary() # 최종 모형 요약 출력