본문으로 건너뛰기

083 스태킹 앙상블 (stack_models)

키워드: stack_models, 스태킹

개요

stack_models()는 여러 기본 모델의 예측을 새로운 특성으로 사용하여 메타 모델이 최종 예측을 수행하는 고급 앙상블 기법입니다. 블렌딩보다 더 복잡하지만 성능 향상 가능성이 높습니다.

실습 환경

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

스태킹이란?

스태킹 (Stacking) 구조:

Level 0 (Base Models):
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Model 1 │ │ Model 2 │ │ Model 3 │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
▼ ▼ ▼
pred₁ pred₂ pred₃

Level 1 (Meta Model):
┌─────────────────────────────────┐
│ Meta Learner │
│ (pred₁, pred₂, pred₃ → Y) │
└─────────────────────────────────┘


최종 예측

기본 사용법

from pycaret.classification import *
from pycaret.datasets import get_data

# 083 데이터 로드
data = get_data('diabetes')

# 083 환경 설정
clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 083 기본 모델 생성
rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')

# 083 스태킹 (기본: 로지스틱 회귀 메타 모델)
stacked = stack_models([rf, xgb, lgbm])

메타 모델 지정

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')

# 083 로지스틱 회귀 메타 모델 (기본)
stacked_lr = stack_models([rf, xgb, lgbm], meta_model=None)

# 083 Ridge 분류기 메타 모델
from sklearn.linear_model import RidgeClassifier
stacked_ridge = stack_models([rf, xgb, lgbm], meta_model=RidgeClassifier())

# 083 랜덤 포레스트 메타 모델
from sklearn.ensemble import RandomForestClassifier
stacked_rf = stack_models([rf, xgb, lgbm], meta_model=RandomForestClassifier(n_estimators=100))

원본 특성 포함

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')

# 083 원본 특성 포함 (메타 모델에 더 많은 정보)
stacked_with_original = stack_models(
[rf, xgb, lgbm],
restack=True # 원본 특성 + 기본 모델 예측
)

# 083 원본 특성 제외 (기본)
stacked_without_original = stack_models(
[rf, xgb, lgbm],
restack=False # 기본 모델 예측만
)

compare_models와 함께 사용

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 083 상위 모델 선택
top5 = compare_models(n_select=5)

# 083 스태킹
stacked = stack_models(top5)

# 083 또는 상위 3개만
top3 = compare_models(n_select=3)
stacked_top3 = stack_models(top3)

튜닝된 모델로 스태킹

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 083 모델 생성 및 튜닝
rf = create_model('rf')
tuned_rf = tune_model(rf, n_iter=20)

xgb = create_model('xgboost')
tuned_xgb = tune_model(xgb, n_iter=20)

lgbm = create_model('lightgbm')
tuned_lgbm = tune_model(lgbm, n_iter=20)

# 083 튜닝된 모델로 스태킹
stacked_tuned = stack_models([tuned_rf, tuned_xgb, tuned_lgbm])

다양한 모델 조합

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 083 다양한 유형의 모델 (추천)
rf = create_model('rf') # 트리 앙상블
lr = create_model('lr') # 선형
svm = create_model('svm') # SVM
knn = create_model('knn') # 거리 기반

# 083 다양성이 높은 스태킹
stacked_diverse = stack_models([rf, lr, svm, knn])

# 083 메타 모델도 단순하게 (과적합 방지)
from sklearn.linear_model import LogisticRegression
stacked_simple = stack_models(
[rf, lr, svm, knn],
meta_model=LogisticRegression(C=0.1) # 정규화 강하게
)

회귀 문제에서 스태킹

from pycaret.regression import *
from pycaret.datasets import get_data

# 083 회귀 데이터
data = get_data('boston')

# 083 환경 설정
reg = setup(data, target='medv', session_id=42, verbose=False)

# 083 기본 모델
rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')
ridge = create_model('ridge')

# 083 스태킹 (회귀)
stacked = stack_models([rf, xgb, lgbm, ridge])

# 083 메타 모델 지정
from sklearn.linear_model import Ridge
stacked_ridge = stack_models(
[rf, xgb, lgbm],
meta_model=Ridge(alpha=1.0)
)

블렌딩 vs 스태킹

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')

# 083 블렌딩
blended = blend_models([rf, xgb, lgbm])

# 083 스태킹
stacked = stack_models([rf, xgb, lgbm])

# 083 비교
all_models = [rf, xgb, lgbm, blended, stacked]
best = compare_models(include=all_models)

차이점

블렌딩 (Voting):
- 단순 평균/다수결
- 학습 없음 (가중치만)
- 빠름
- 해석 쉬움

스태킹:
- 메타 모델이 학습
- 기본 모델 예측을 특성으로 사용
- 느림 (2단계 학습)
- 복잡함
- 성능 향상 가능성 높음

다단계 스태킹

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

# 083 Level 0: 다양한 모델
rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')
knn = create_model('knn')
lr = create_model('lr')

# 083 Level 1: 첫 번째 스태킹
stack1 = stack_models([rf, xgb, lgbm])
stack2 = stack_models([knn, lr])

# 083 Level 2: 두 번째 스태킹 (선택적)
# 083 주의: 과적합 위험 증가
# 083 final_stack = stack_models([stack1, stack2])

스태킹 모델 저장

from pycaret.classification import *

clf = setup(data, target='Class variable', session_id=42, verbose=False)

rf = create_model('rf')
xgb = create_model('xgboost')
lgbm = create_model('lightgbm')

# 083 스태킹
stacked = stack_models([rf, xgb, lgbm])

# 083 전체 데이터로 재학습
final_model = finalize_model(stacked)

# 083 저장
save_model(final_model, 'stacked_model')

# 083 로드 및 예측
loaded = load_model('stacked_model')
predictions = predict_model(loaded, data=data.head())

스태킹 주의사항

주의사항:

1. 데이터 누출 방지
- 기본 모델 학습에 사용한 데이터로
메타 모델 학습하면 안 됨
- PyCaret은 자동으로 교차 검증 사용

2. 과적합 위험
- 너무 많은 기본 모델
- 복잡한 메타 모델
- 다단계 스태킹

3. 계산 비용
- 기본 모델 수 × 폴드 수 만큼 학습
- 예측 시 모든 모델 실행

4. 해석 어려움
- 어떤 모델이 기여하는지 불명확
- 규제 산업에서 문제

언제 스태킹을 사용하나?

스태킹 추천:
- 성능이 최우선일 때
- 충분한 계산 자원
- 다양한 모델이 비슷한 성능
- 대회/경쟁 환경

스태킹 비추천:
- 실시간 예측 필요
- 해석 가능성 중요
- 데이터가 적을 때 (과적합)
- 단일 모델이 충분히 좋을 때

정리

  • stack_models(): 메타 모델 기반 앙상블
  • 기본 모델 예측 → 새 특성 → 메타 모델
  • restack=True: 원본 특성 포함
  • 다양한 모델 조합 효과적
  • 블렌딩보다 복잡하지만 성능 향상 가능

다음 글 예고

다음 글에서는 모델 해석 - SHAP을 다룹니다.


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