🤖 AI/ML

그래디언트 부스팅

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초

🗣️ 실무에서 이렇게 말하세요

PM:
"이번 고객 이탈 예측 모델, 어떤 알고리즘 쓸 건가요? 딥러닝?"
ML 엔지니어:
"정형 데이터라 LightGBM으로 시작합니다. 데이터 100만 건인데 학습 시간도 빠르고, 범주형 피처 50개는 CatBoost가 더 나을 수도 있어서 둘 다 비교해볼게요. 하이퍼파라미터는 Optuna로 튜닝하고, early_stopping 걸어서 과적합 방지하겠습니다."

⚠️ 흔한 실수 & 주의사항

n_estimators를 매우 크게 설정하고 early_stopping 없이 학습
early_stopping_rounds와 함께 사용하여 최적 트리 개수 자동 결정
학습률(learning_rate)을 너무 높게 설정하여 과적합 발생
0.01~0.1 범위에서 시작하고, 트리 개수와 함께 조정
범주형 변수를 원핫 인코딩 없이 그대로 XGBoost에 입력
XGBoost는 범주형 인코딩 필요, CatBoost는 cat_features 지정으로 자동 처리

🔗 관련 용어

📚 더 배우기