029 Gradient Boosting 분류 상세
키워드: Gradient Boosting, gbc
개요
Gradient Boosting은 약한 학습기(주로 결정 트리)를 순차적으로 학습하여 이전 모델의 오차를 보완하는 앙상블 기법입니다. 높은 예측 성능으로 유명합니다.
실습 환경
- Python 버전: 3.11 권장
- 필요 패키지:
pycaret[full]>=3.0
Gradient Boosting 원리
- 초기 모델로 예측
- 잔차(실제값 - 예측값)를 계산
- 잔차를 타겟으로 새 트리 학습
- 기존 모델에 새 트리를 추가 (learning_rate로 가중)
- 2-4 반복
F₀(x) → 잔차 계산 → h₁(x) 학습 → F₁(x) = F₀(x) + η·h₁(x)
→ 잔차 계산 → h₂(x) 학습 → F₂(x) = F₁(x) + η·h₂(x)
→ ... → Fₙ(x)
PyCaret에서 Gradient Boosting
from pycaret.classification import *
from pycaret.datasets import get_data
# 029 데이터 로드
data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)
# 029 Gradient Boosting 모델 생성
gbc = create_model('gbc')
주요 하이퍼파라미터
# 029 n_estimators: 부스팅 단계 수 (트리 개수)
gbc_100 = create_model('gbc', n_estimators=100) # 기본값
gbc_200 = create_model('gbc', n_estimators=200)
# 029 learning_rate: 각 트리의 기여도 (shrinkage)
gbc_lr01 = create_model('gbc', learning_rate=0.1) # 기본값
gbc_lr005 = create_model('gbc', learning_rate=0.05) # 더 느리지만 안정적
gbc_lr001 = create_model('gbc', learning_rate=0.01) # n_estimators 증가 필요
# 029 max_depth: 개별 트리 깊이
gbc_d3 = create_model('gbc', max_depth=3) # 기본값
gbc_d5 = create_model('gbc', max_depth=5)
# 029 subsample: 각 트리 학습에 사용할 샘플 비율
gbc_sub = create_model('gbc', subsample=0.8)
# 029 min_samples_split, min_samples_leaf
gbc_split = create_model('gbc', min_samples_split=10)
gbc_leaf = create_model('gbc', min_samples_leaf=5)
Learning Rate와 n_estimators 관계
from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd
data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)
# 029 learning_rate가 작으면 n_estimators를 늘려야 함
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:
gbc = create_model('gbc', **config, verbose=False)
metrics = pull()
results.append({
'lr': config['learning_rate'],
'n_est': config['n_estimators'],
'accuracy': metrics['Accuracy'].mean(),
'auc': metrics['AUC'].mean()
})
df = pd.DataFrame(results)
print(df)
# 029 일반적으로 lr 낮추고 n_estimators 높이면 성능 향상
# 029 하지만 학습 시간 증가
Early Stopping
과적합 방지를 위한 조기 종료:
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)
# 029 PyCaret에서는 직접 지원하지 않음
# 029 sklearn의 warm_start 또는 XGBoost/LightGBM 사용 권장
# 029 수동 구현 예시
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
X_train = get_config('X_train')
y_train = get_config('y_train')
X_tr, X_val, y_tr, y_val = train_test_split(
X_train, y_train, test_size=0.2, random_state=42
)
# 029 Early stopping 구현
best_n = 100
best_score = 0
for n in range(50, 501, 50):
gbc = GradientBoostingClassifier(
n_estimators=n,
learning_rate=0.1,
random_state=42
)
gbc.fit(X_tr, y_tr)
score = gbc.score(X_val, y_val)
print(f"n_estimators={n}, val_score={score:.4f}")
if score > best_score:
best_score = score
best_n = n
elif score < best_score - 0.01: # 성능 하락 시 중단
print(f"Early stopping at n={n}")
break
print(f"\nBest n_estimators: {best_n}")
Staged Predict
학습 과정의 각 단계별 예측:
from pycaret.classification import *
from pycaret.datasets import get_data
import matplotlib.pyplot as plt
import numpy as np
data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)
gbc = create_model('gbc', n_estimators=200, verbose=False)
X_test = get_config('X_test')
y_test = get_config('y_test')
# 029 각 단계별 점수
scores = []
for y_pred in gbc.staged_predict(X_test):
score = np.mean(y_pred == y_test)
scores.append(score)
plt.figure(figsize=(10, 6))
plt.plot(range(1, len(scores)+1), scores)
plt.xlabel('Number of Trees')
plt.ylabel('Accuracy')
plt.title('Gradient Boosting: Performance vs Number of Trees')
plt.grid(True)
plt.savefig('gbc_staging.png', dpi=150)
특성 중요도
from pycaret.classification import *
from pycaret.datasets import get_data
import pandas as pd
data = get_data('diabetes')
clf = setup(data, target='Class variable', session_id=42, verbose=False)
gbc = create_model('gbc', verbose=False)
# 029 특성 중요도
feature_names = get_config('X_train').columns
importances = gbc.feature_importances_
importance_df = pd.DataFrame({
'feature': feature_names,
'importance': importances
}).sort_values('importance', ascending=False)
print(importance_df)
# 029 시각화
plot_model(gbc, plot='feature')
튜닝
from pycaret.classification import *
from pycaret.datasets import get_data
data = get_data('credit')
clf = setup(data, target='default', session_id=42, verbose=False)
# 029 기본 모델
gbc = create_model('gbc', verbose=False)
# 029 자동 튜닝
tuned_gbc = tune_model(gbc, optimize='AUC')
# 029 커스텀 그리드
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_gbc = tune_model(gbc, custom_grid=custom_grid, optimize='AUC')
장단점
장점:
- 매우 높은 예측 성능
- 다양한 손실 함수 지원
- 특성 중요도 제공
- 결측치에 어느 정도 강건
단점:
- 학습 시간이 오래 걸림
- 순차적 학습으로 병렬화 어려움
- 하이퍼파라미터 튜닝 필요
- 과적합 위험 (early stopping 필요)
- 해석이 어려움
Gradient Boosting vs Random Forest
| 항목 | Gradient Boosting | Random Forest |
|---|---|---|
| 학습 방식 | 순차적 (Boosting) | 병렬 (Bagging) |
| 과적합 | 위험 높음 | 위험 낮음 |
| 튜닝 민감도 | 높음 | 낮음 |
| 학습 속도 | 느림 | 빠름 |
| 최종 성능 | 보통 더 높음 | 보통 |
정리
- Gradient Boosting은 순차적 앙상블 기법
- learning_rate와 n_estimators의 균형이 중요
- learning_rate를 낮추면 성능 향상 가능 (시간 증가)
- subsample로 과적합 방지
- XGBoost, LightGBM이 더 빠르고 성능 좋음
다음 글 예고
다음 글에서는 XGBoost 분류 상세를 다룹니다.
PyCaret 머신러닝 마스터 시리즈 #029