그래디언트 부스팅
Gradient Boosting
약한 학습기를 순차적으로 결합하는 앙상블 기법. XGBoost, LightGBM.
Gradient Boosting
약한 학습기를 순차적으로 결합하는 앙상블 기법. XGBoost, LightGBM.
그래디언트 부스팅(Gradient Boosting)은 여러 개의 약한 학습기(주로 결정 트리)를 순차적으로 결합하여 강력한 예측 모델을 만드는 앙상블 기법입니다. 각 단계에서 이전 모델의 잔차(residual), 즉 오차를 학습하는 새로운 모델을 추가합니다. 이 과정에서 경사하강법(Gradient Descent)을 사용하여 손실 함수를 최소화하는 방향으로 모델을 개선해 나갑니다.
부스팅의 핵심 아이디어는 "이전 모델이 틀린 부분에 집중하라"입니다. 첫 번째 트리가 예측한 오차를 두 번째 트리가 학습하고, 그 오차를 다시 세 번째 트리가 학습하는 식으로 반복합니다. 최종 예측은 모든 트리 예측의 합으로 계산됩니다. 이 방식은 랜덤 포레스트처럼 병렬로 학습하는 배깅(Bagging)과 달리 순차적으로 학습하므로 이전 모델의 약점을 보완할 수 있습니다.
실무에서 가장 많이 사용되는 구현체로 XGBoost, LightGBM, CatBoost가 있습니다. XGBoost는 정규화와 병렬 처리 최적화로 Kaggle 대회에서 많은 우승을 차지했습니다. LightGBM은 리프 중심 트리 성장 방식으로 대규모 데이터에서 더 빠릅니다. CatBoost는 범주형 변수를 별도 전처리 없이 처리하고 순서 의존 타깃 인코딩으로 과적합을 줄입니다.
그래디언트 부스팅은 정형 데이터(tabular data)에서 여전히 딥러닝보다 우수한 성능을 보이는 경우가 많습니다. 특히 피처 엔지니어링과 하이퍼파라미터 튜닝에 민감하므로, 학습률(learning_rate), 트리 개수(n_estimators), 트리 깊이(max_depth), 정규화 파라미터(reg_alpha, reg_lambda)를 신중하게 조정해야 합니다. 과적합 방지를 위해 조기 종료(early stopping)를 함께 사용하는 것이 일반적입니다.
XGBoost, LightGBM, CatBoost 세 가지 구현체를 비교하는 예제입니다.
# pip install xgboost lightgbm catboost scikit-learn
import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.metrics import accuracy_score, classification_report
import xgboost as xgb
import lightgbm as lgb
from catboost import CatBoostClassifier
import time
# 데이터 생성
X, y = make_classification(n_samples=10000, n_features=20, n_informative=15,
n_redundant=3, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 1. XGBoost
print("=== XGBoost ===")
start = time.time()
xgb_model = xgb.XGBClassifier(
n_estimators=100,
max_depth=6,
learning_rate=0.1,
subsample=0.8,
colsample_bytree=0.8,
reg_alpha=0.1,
reg_lambda=1.0,
early_stopping_rounds=10,
eval_metric='logloss',
random_state=42
)
xgb_model.fit(X_train, y_train, eval_set=[(X_test, y_test)], verbose=False)
xgb_pred = xgb_model.predict(X_test)
print(f"정확도: {accuracy_score(y_test, xgb_pred):.4f}")
print(f"학습 시간: {time.time() - start:.2f}초")
# 2. LightGBM
print("\n=== LightGBM ===")
start = time.time()
lgb_model = lgb.LGBMClassifier(
n_estimators=100,
max_depth=6,
learning_rate=0.1,
subsample=0.8,
colsample_bytree=0.8,
reg_alpha=0.1,
reg_lambda=1.0,
random_state=42,
verbose=-1
)
lgb_model.fit(
X_train, y_train,
eval_set=[(X_test, y_test)],
callbacks=[lgb.early_stopping(stopping_rounds=10, verbose=False)]
)
lgb_pred = lgb_model.predict(X_test)
print(f"정확도: {accuracy_score(y_test, lgb_pred):.4f}")
print(f"학습 시간: {time.time() - start:.2f}초")
# 3. CatBoost
print("\n=== CatBoost ===")
start = time.time()
cat_model = CatBoostClassifier(
iterations=100,
depth=6,
learning_rate=0.1,
l2_leaf_reg=3.0,
random_seed=42,
verbose=False,
early_stopping_rounds=10
)
cat_model.fit(X_train, y_train, eval_set=(X_test, y_test))
cat_pred = cat_model.predict(X_test)
print(f"정확도: {accuracy_score(y_test, cat_pred):.4f}")
print(f"학습 시간: {time.time() - start:.2f}초")
# 피처 중요도 (XGBoost)
print("\n=== XGBoost 피처 중요도 Top 5 ===")
importance = xgb_model.feature_importances_
indices = np.argsort(importance)[::-1][:5]
for i, idx in enumerate(indices):
print(f"{i+1}. Feature {idx}: {importance[idx]:.4f}")
# 결과 예시:
# === XGBoost ===
# 정확도: 0.9285
# 학습 시간: 0.42초
#
# === LightGBM ===
# 정확도: 0.9310
# 학습 시간: 0.18초