본문으로 건너뛰기

029 Gradient Boosting 분류 상세

키워드: Gradient Boosting, gbc

개요

Gradient Boosting은 약한 학습기(주로 결정 트리)를 순차적으로 학습하여 이전 모델의 오차를 보완하는 앙상블 기법입니다. 높은 예측 성능으로 유명합니다.

실습 환경

  • Python 버전: 3.11 권장
  • 필요 패키지: pycaret[full]>=3.0

Gradient Boosting 원리

  1. 초기 모델로 예측
  2. 잔차(실제값 - 예측값)를 계산
  3. 잔차를 타겟으로 새 트리 학습
  4. 기존 모델에 새 트리를 추가 (learning_rate로 가중)
  5. 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 BoostingRandom Forest
학습 방식순차적 (Boosting)병렬 (Bagging)
과적합위험 높음위험 낮음
튜닝 민감도높음낮음
학습 속도느림빠름
최종 성능보통 더 높음보통

정리

  • Gradient Boosting은 순차적 앙상블 기법
  • learning_rate와 n_estimators의 균형이 중요
  • learning_rate를 낮추면 성능 향상 가능 (시간 증가)
  • subsample로 과적합 방지
  • XGBoost, LightGBM이 더 빠르고 성능 좋음

다음 글 예고

다음 글에서는 XGBoost 분류 상세를 다룹니다.


PyCaret 머신러닝 마스터 시리즈 #029