049 Gradient Boosting 회귀 상세
키워드: Gradient Boosting, 회귀
개요
Gradient Boosting은 약한 학습기를 순차적으로 결합하는 앙상블 기법입니다. 회귀에서 잔차를 반복적으로 줄여나가며 강력한 예측 모델을 구축합니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
pycaret[full]>=3.0
Gradient Boosting 회귀 원리
- 초기 모델: 타겟의 평균값으로 예측
- 잔차(실제 - 예측) 계산
- 잔차를 예측하는 새 트리 학습
- 기존 모델에 새 트리 추가 (learning_rate로 가중)
- 2-4 반복
F₀(x) = 평균값
잔차₁ = y - F₀(x)
h₁(x) = 잔차₁ 예측 트리
F₁(x) = F₀(x) + η × h₁(x)
...
PyCaret에서 Gradient Boosting 회귀
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
# 049 Gradient Boosting 회귀
gbr = create_model('gbr')
주요 하이퍼파라미터
# 049 n_estimators: 부스팅 단계 수
gbr_100 = create_model('gbr', n_estimators=100)
gbr_200 = create_model('gbr', n_estimators=200)
# 049 learning_rate: 각 트리의 기여도
gbr_lr01 = create_model('gbr', learning_rate=0.1)
gbr_lr005 = create_model('gbr', learning_rate=0.05)
# 049 max_depth: 개별 트리 깊이
gbr_d3 = create_model('gbr', max_depth=3)
gbr_d5 = create_model('gbr', max_depth=5)
# 049 subsample: 샘플 비율
gbr_sub = create_model('gbr', subsample=0.8)
# 049 min_samples_split, min_samples_leaf
gbr_split = create_model('gbr', min_samples_split=10)
Learning Rate와 n_estimators 관계
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)
configs = [
{'learning_rate': 0.1, 'n_estimators': 100},
{'learning_rate': 0.05, 'n_estimators': 200},
{'learning_rate': 0.01, 'n_estimators': 500},
]
results = []
for config in configs:
gbr = create_model('gbr', **config, verbose=False)
metrics = pull()
results.append({
'lr': config['learning_rate'],
'n_est': config['n_estimators'],
'RMSE': metrics['RMSE'].mean(),
'R2': metrics['R2'].mean()
})
df = pd.DataFrame(results)
print(df)
# 049 learning_rate 낮추고 n_estimators 높이면 성능 향상 (시간 증가)
Staged Predict
import matplotlib.pyplot as plt
import numpy as np
# 049 학습 단계별 성능 추적
gbr = create_model('gbr', n_estimators=200, verbose=False)
X_test = get_config('X_test')
y_test = get_config('y_test')
# 049 각 단계별 RMSE
staged_scores = []
for y_pred in gbr.staged_predict(X_test):
rmse = np.sqrt(np.mean((y_test - y_pred) ** 2))
staged_scores.append(rmse)
plt.figure(figsize=(10, 6))
plt.plot(range(1, len(staged_scores) + 1), staged_scores)
plt.xlabel('Number of Trees')
plt.ylabel('RMSE')
plt.title('Gradient Boosting: RMSE vs Number of Trees')
plt.grid(True)
plt.savefig('gbr_staged_rmse.png', dpi=150)
손실 함수
# 049 loss: 손실 함수 선택
gbr_ls = create_model('gbr', loss='squared_error') # 기본값, MSE
gbr_lad = create_model('gbr', loss='absolute_error') # MAE, 이상치에 강건
gbr_huber = create_model('gbr', loss='huber') # Huber, 절충안
gbr_quantile = create_model('gbr', loss='quantile', alpha=0.5) # 분위수 회귀
Huber 손실
이상치에 강건한 손실 함수:
from pycaret.regression import *
from pycaret.datasets import get_data
import numpy as np
# 049 이상치가 있는 데이터 시뮬레이션
data = get_data('boston')
# 049 일부 이상치 추가
data_outlier = data.copy()
outlier_idx = np.random.choice(len(data), 20, replace=False)
data_outlier.loc[outlier_idx, 'medv'] *= 3 # 가격 3배
reg = setup(data_outlier, target='medv', session_id=42, verbose=False)
# 049 일반 MSE
print("=== Squared Error (MSE) ===")
gbr_mse = create_model('gbr', loss='squared_error')
# 049 Huber 손실 (이상치에 강건)
print("\n=== Huber Loss ===")
gbr_huber = create_model('gbr', loss='huber', alpha=0.9)
튜닝
from pycaret.regression import *
from pycaret.datasets import get_data
data = get_data('boston')
reg = setup(data, target='medv', session_id=42, verbose=False)
gbr = create_model('gbr', verbose=False)
# 049 자동 튜닝
tuned_gbr = tune_model(gbr, optimize='RMSE')
# 049 커스텀 그리드
custom_grid = {
'n_estimators': [100, 200, 300],
'learning_rate': [0.01, 0.05, 0.1],
'max_depth': [3, 4, 5],
'subsample': [0.8, 0.9, 1.0],
'min_samples_split': [2, 5, 10]
}
tuned_gbr = tune_model(gbr, custom_grid=custom_grid, optimize='RMSE')
특성 중요도
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)
gbr = create_model('gbr', verbose=False)
# 049 특성 중요도
feature_names = get_config('X_train').columns
importances = gbr.feature_importances_
importance_df = pd.DataFrame({
'Feature': feature_names,
'Importance': importances
}).sort_values('Importance', ascending=False)
print(importance_df)
plot_model(gbr, plot='feature')
장단점
장점:
- 매우 높은 예측 성능
- 다양한 손실 함수 지원
- 특성 중요도 제공
- 이상치 처리 가능 (Huber)
단점:
- 학습 시간 오래 걸림
- 순차적 학습 (병렬화 어려움)
- 하이퍼파라미터 튜닝 필요
- 과적합 위험 (early stopping 필요)
Gradient Boosting vs Random Forest
| 항목 | Gradient Boosting | Random Forest |
|---|---|---|
| 학습 방식 | 순차적 | 병렬 |
| 과적합 | 위험 높음 | 위험 낮음 |
| 튜닝 | 민감함 | 덜 민감 |
| 속도 | 느림 | 빠름 |
| 최종 성능 | 보통 더 높음 | 좋음 |
정리
- Gradient Boosting은 잔차를 순차적으로 줄여나감
- learning_rate와 n_estimators의 균형이 중요
- Huber 손실로 이상치에 대응
- XGBoost, LightGBM이 더 빠르고 효율적
- 튜닝이 성능에 큰 영향
다음 글 예고
다음 글에서는 XGBoost 회귀 상세를 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #049