052 회귀 알고리즘 선택 가이드
키워드: 알고리즘 선택, 회귀
개요
다양한 회귀 알고리즘 중 어떤 것을 선택해야 할까요? 이 글에서는 데이터 특성과 문제 상황에 따른 회귀 알고리즘 선택 기준을 제시합니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
pycaret[full]>=3.0
알고리즘 특성 요약
| 알고리즘 | 속도 | 해석력 | 비선형 | 스케일링 | 이상치 | 고차원 |
|---|---|---|---|---|---|---|
| 선형 회귀 | 빠름 | 높음 | X | 필요 | 민감 | 약함 |
| Ridge | 빠름 | 높음 | X | 필요 | 민감 | 좋음 |
| Lasso | 빠름 | 높음 | X | 필요 | 민감 | 좋음 |
| 결정 트리 | 빠름 | 중간 | O | 불필요 | 보통 | 보통 |
| 랜덤 포레스트 | 보통 | 낮음 | O | 불필요 | 강건 | 좋음 |
| Gradient Boosting | 느림 | 낮음 | O | 불필요 | 보통 | 좋음 |
| XGBoost | 보통 | 낮음 | O | 불필요 | 보통 | 좋음 |
| LightGBM | 빠름 | 낮음 | O | 불필요 | 보통 | 매우 좋음 |
상황별 알고리즘 선택
1. 데이터 크기에 따른 선택
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
n_samples = len(data)
if n_samples < 1000:
# 소규모: 과적합 주의
recommended = ['lr', 'ridge', 'lasso', 'rf']
elif n_samples < 100000:
# 중규모: 대부분 알고리즘 가능
recommended = ['rf', 'xgboost', 'lightgbm', 'gbr']
else:
# 대규모: 효율성 중요
recommended = ['lightgbm', 'xgboost']
print(f"데이터 크기: {n_samples}")
print(f"추천 알고리즘: {recommended}")
2. 특성 수에 따른 선택
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
n_features = len(get_config('X_train').columns)
n_samples = len(get_config('X_train'))
ratio = n_samples / n_features
if ratio < 10:
# 특성이 많음 (고차원)
recommended = ['lasso', 'en', 'ridge']
print("고차원 데이터: Lasso/Ridge로 특성 선택 효과")
elif n_features > 100:
# 특성이 중간 정도
recommended = ['lightgbm', 'xgboost', 'rf']
print("많은 특성: 트리 기반 알고리즘 추천")
else:
# 특성이 적음
recommended = ['lr', 'ridge', 'rf', 'xgboost']
print("적은 특성: 대부분 알고리즘 가능")
3. 관계의 선형성에 따른 선택
import numpy as np
from sklearn.feature_selection import f_regression
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
X = get_config('X_train')
y = get_config('y_train')
# 052 F-통계량으로 선형 관계 강도 확인
f_scores, p_values = f_regression(X, y)
# 052 높은 F-score = 강한 선형 관계
print("선형 관계 강도 (F-score):")
for name, score in zip(X.columns, f_scores):
print(f" {name}: {score:.2f}")
# 052 선형 관계가 강하면 선형 모델
# 052 비선형이면 트리 기반 모델
4. 해석 가능성 요구에 따른 선택
from pycaret.regression import *
from pycaret.datasets import get_data
import pandas as pd
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 052 고해석력: 선형 모델
lr = create_model('lr', verbose=False)
print("\n선형 회귀 계수:")
coef_df = pd.DataFrame({
'Feature': get_config('X_train').columns,
'Coefficient': lr.coef_
}).sort_values('Coefficient', key=abs, ascending=False)
print(coef_df)
# 052 중해석력: 결정 트리
dt = create_model('dt', max_depth=4, verbose=False)
print(f"\n결정 트리 깊이: {dt.get_depth()}")
print("plot_model(dt, plot='tree')로 시각화 가능")
# 052 저해석력 (SHAP 필요): 앙상블
xgb = create_model('xgboost', verbose=False)
print("\nXGBoost는 SHAP으로 해석")
의사결정 플로우차트
def recommend_algorithm(data_size, n_features, need_interpretation, is_linear):
"""회귀 알고리즘 추천"""
if need_interpretation:
if is_linear:
return ['lr', 'ridge', 'lasso']
else:
return ['dt', 'rf'] # SHAP 활용
if data_size < 1000:
if n_features > 50:
return ['lasso', 'ridge', 'en']
else:
return ['rf', 'ridge', 'xgboost']
elif data_size < 100000:
if is_linear:
return ['ridge', 'lasso', 'lr']
else:
return ['xgboost', 'lightgbm', 'rf']
else: # 대용량
return ['lightgbm', 'xgboost']
# 052 예시
print(recommend_algorithm(
data_size=5000,
n_features=20,
need_interpretation=False,
is_linear=False
))
알고리즘별 상세 가이드
선형 회귀 계열 (lr, ridge, lasso, en)
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 052 언제 사용?
# 052 - 선형 관계가 명확할 때
# 052 - 해석이 중요할 때
# 052 - 빠른 학습이 필요할 때
# 052 어떤 것을 선택?
# 052 lr: 기본, 다중공선성 없을 때
# 052 ridge: 다중공선성 있을 때
# 052 lasso: 특성 선택 필요할 때
# 052 en: 불확실할 때 (ridge + lasso)
models = {}
for name in ['lr', 'ridge', 'lasso', 'en']:
models[name] = create_model(name, verbose=False)
print(f"{name}: RMSE = {pull()['RMSE'].mean():.4f}")
결정 트리 (dt)
# 052 언제 사용?
# 052 - 규칙 기반 해석 필요
# 052 - 비선형 관계
# 052 - 빠른 프로토타이핑
# 052 주의점
# 052 - 과적합 경향
# 052 - 불안정 (데이터 변화에 민감)
# 052 - 앙상블의 기반으로 주로 사용
dt = create_model('dt', max_depth=5, verbose=False)
랜덤 포레스트 (rf)
# 052 언제 사용?
# 052 - 안정적인 성능 필요
# 052 - 튜닝에 많은 시간 투자 어려움
# 052 - 이상치에 강건해야 함
# 052 장점
# 052 - 과적합에 강건
# 052 - 하이퍼파라미터 덜 민감
# 052 - OOB Score로 검증 가능
rf = create_model('rf', n_estimators=100, verbose=False)
Gradient Boosting 계열 (gbr, xgboost, lightgbm)
# 052 언제 사용?
# 052 - 최고 성능 필요
# 052 - 충분한 튜닝 시간 있음
# 052 - 대회/프로덕션
# 052 어떤 것을 선택?
# 052 gbr: 소규모, scikit-learn 생태계
# 052 xgboost: 범용, 안정적
# 052 lightgbm: 대용량, 빠른 학습
# 052 성능 비교
for name in ['gbr', 'xgboost', 'lightgbm']:
model = create_model(name, verbose=False)
print(f"{name}: RMSE = {pull()['RMSE'].mean():.4f}")
전체 비교 실험
from pycaret.regression import *
from pycaret.datasets import get_data
import time
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 052 모든 모델 비교
results = []
algorithms = {
'선형 회귀': 'lr',
'Ridge': 'ridge',
'Lasso': 'lasso',
'Elastic Net': 'en',
'결정 트리': 'dt',
'랜덤 포레스트': 'rf',
'Gradient Boosting': 'gbr',
'XGBoost': 'xgboost',
'LightGBM': 'lightgbm'
}
for name, model_id in algorithms.items():
start = time.time()
model = create_model(model_id, verbose=False)
elapsed = time.time() - start
metrics = pull()
results.append({
'Algorithm': name,
'RMSE': metrics['RMSE'].mean(),
'R2': metrics['R2'].mean(),
'Time (s)': elapsed
})
import pandas as pd
df = pd.DataFrame(results).sort_values('RMSE')
print(df)
앙상블 전략
단일 알고리즘으로 부족할 때:
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 052 상위 모델 선택
xgb = create_model('xgboost', verbose=False)
lgbm = create_model('lightgbm', verbose=False)
rf = create_model('rf', verbose=False)
# 052 블렌딩
blended = blend_models([xgb, lgbm, rf])
# 052 스태킹
stacked = stack_models([xgb, lgbm, rf])
# 052 앙상블은 보통 단일 모델보다 좋은 성능
빠른 선택 가이드
시작
│
├─ 해석이 중요한가?
│ ├─ Yes → 선형 관계? → Yes → lr/ridge/lasso
│ │ → No → dt (얕은 깊이)
│ └─ No ↓
│
├─ 데이터 크기?
│ ├─ <1000 → rf (과적합 방지)
│ ├─ 1000-100k → xgboost/lightgbm
│ └─ >100k → lightgbm
│
├─ 고차원 (특성 > 샘플)?
│ └─ Yes → lasso/ridge/en
│
└─ 최고 성능 필요?
└─ Yes → compare_models() + 앙상블
정리
- 선형 + 해석: lr, ridge, lasso
- 비선형 + 안정성: rf
- 최고 성능: xgboost, lightgbm
- 대용량: lightgbm
- 고차원: lasso, ridge
- 불확실: compare_models() 사용
compare_models() 활용
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 052 모든 모델 자동 비교
best = compare_models()
# 052 상위 N개 반환
top3 = compare_models(n_select=3)
# 052 특정 메트릭으로 정렬
best_r2 = compare_models(sort='R2')
# 052 특정 모델만 비교
selected = compare_models(include=['lr', 'ridge', 'rf', 'xgboost', 'lightgbm'])
다음 글 예고
다음 글에서는 회귀 실전 - 매출 예측을 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #052