🤖 AI/ML

앙상블

Ensemble Learning

여러 모델 결합하여 성능 향상. 배깅, 부스팅, 스태킹.

📖 상세 설명

앙상블(Ensemble Learning)은 여러 개의 개별 모델(base learner)을 결합하여 단일 모델보다 더 나은 예측 성능을 얻는 머신러닝 기법입니다. "삼인성호(三人成虎)" 또는 "집단 지성"의 원리와 유사하게, 다양한 관점의 예측을 종합하면 개별 모델의 약점을 보완하고 일반화 성능을 향상시킬 수 있습니다.

앙상블 기법의 역사는 1990년대 배깅(Bagging)과 부스팅(Boosting)의 등장으로 시작되었습니다. 2001년 Leo Breiman의 랜덤 포레스트, 2016년 XGBoost의 Kaggle 대회 석권, 그리고 2017년 LightGBM과 CatBoost의 등장으로 테이블 데이터 분석의 표준이 되었습니다. 2024년에는 딥러닝과 그래디언트 부스팅을 결합한 TabNet, TabPFN 등 하이브리드 모델도 활발히 연구되고 있습니다.

앙상블의 세 가지 주요 기법은 배깅(Bagging), 부스팅(Boosting), 스태킹(Stacking)입니다. 배깅은 부트스트랩 샘플링으로 독립적인 모델을 병렬 학습하고, 부스팅은 이전 모델의 오류를 보정하며 순차적으로 학습합니다. 스태킹은 1단계 모델들의 예측을 2단계 메타 모델의 입력으로 사용하여 최종 예측을 수행합니다.

실무에서는 Kaggle 등 데이터 과학 대회에서 거의 모든 상위 솔루션이 앙상블을 활용합니다. 특히 XGBoost, LightGBM, CatBoost를 함께 사용하는 "GBDT 앙상블"이 테이블 데이터에서 가장 높은 성능을 보이며, 금융 사기 탐지, 추천 시스템, 의료 진단 등에 널리 적용됩니다.

💻 코드 예제

# 앙상블 학습 - 스태킹 예제
# pip install scikit-learn xgboost lightgbm catboost

import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import RandomForestClassifier, StackingClassifier
from sklearn.linear_model import LogisticRegression
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from catboost import CatBoostClassifier

# 샘플 데이터 생성
X, y = make_classification(n_samples=10000, n_features=20,
                          n_informative=15, random_state=42)

# 1단계: Base Learners 정의
base_learners = [
    ('rf', RandomForestClassifier(n_estimators=100, random_state=42)),
    ('xgb', XGBClassifier(n_estimators=100, random_state=42, verbosity=0)),
    ('lgb', LGBMClassifier(n_estimators=100, random_state=42, verbose=-1)),
    ('cat', CatBoostClassifier(iterations=100, random_state=42, verbose=0))
]

# 2단계: Meta Learner (스태킹)
stacking_clf = StackingClassifier(
    estimators=base_learners,
    final_estimator=LogisticRegression(),
    cv=5,
    stack_method='predict_proba'
)

# 개별 모델 vs 스태킹 성능 비교
print("=== 앙상블 성능 비교 ===")
for name, model in base_learners:
    scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
    print(f"{name:4s}: {scores.mean():.4f} (+/- {scores.std()*2:.4f})")

# 스태킹 앙상블
stacking_scores = cross_val_score(stacking_clf, X, y, cv=5, scoring='accuracy')
print(f"{'Stack':4s}: {stacking_scores.mean():.4f} (+/- {stacking_scores.std()*2:.4f})")

# 출력 예시:
# rf  : 0.9234 (+/- 0.0156)
# xgb : 0.9312 (+/- 0.0142)
# lgb : 0.9298 (+/- 0.0138)
# cat : 0.9325 (+/- 0.0144)
# Stack: 0.9412 (+/- 0.0128)  <- 스태킹이 개별 모델보다 높은 성능!

📊 성능 & 비용

주요 앙상블 알고리즘 비교 (2025년 1월 기준):

알고리즘 유형 특징 학습 속도
Random Forest 배깅 병렬 처리, 과적합 방지 빠름 (병렬)
XGBoost 부스팅 정규화, GPU 지원 중간
LightGBM 부스팅 Leaf-wise, 대용량 데이터 매우 빠름
CatBoost 부스팅 범주형 자동 처리 중간
Stacking 메타 다양한 모델 결합 느림 (N배)

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

💬 회의에서
"단일 XGBoost로 AUC 0.92가 나왔는데, LightGBM과 CatBoost를 스태킹하면 0.95까지 올릴 수 있을 것 같습니다. 추론 시간이 3배 늘어나지만, 사기 탐지에서는 정확도가 더 중요하니까요."
💬 면접에서
"앙상블이 효과적인 이유는 Bias-Variance Tradeoff 관점에서 설명할 수 있습니다. 배깅은 분산을 줄이고, 부스팅은 편향을 줄입니다. 다양한 모델을 결합하면 두 가지 모두 개선할 수 있어요."
💬 기술 토론에서
"Kaggle 대회에서는 거의 모든 우승 솔루션이 앙상블을 씁니다. 하지만 프로덕션에서는 추론 비용과 유지보수 복잡성을 고려해야 해요. 가벼운 Voting 앙상블이나 지식 증류로 단일 모델로 압축하는 것도 좋은 방법입니다."

⚠️ 흔한 실수 & 주의사항

동일한 모델만 앙상블

같은 알고리즘을 여러 개 결합하면 다양성(Diversity)이 부족합니다. Random Forest + XGBoost + LightGBM처럼 서로 다른 알고리즘을 결합해야 효과가 극대화됩니다.

검증 데이터 누수

스태킹에서 1단계 모델의 예측을 만들 때 같은 데이터로 학습하고 예측하면 과적합됩니다. 반드시 Out-of-Fold 예측을 사용하세요.

올바른 방법

K-Fold CV로 각 폴드에서 학습된 모델로 나머지 데이터를 예측하는 Out-of-Fold 방식을 사용하세요. 또한 앙상블 전에 개별 모델의 하이퍼파라미터 튜닝을 먼저 완료해야 합니다.

🔗 관련 용어

📚 더 배우기