ML 🐼/머신러닝 💕

[핸즈온머신러닝] 앙상블(Ensemble) 학습 (2) [부스팅 ~ 스태킹]

Dobby98 2022. 11. 30. 17:42

목차 

  1. 앙상블 기법이란?
  2. 앙상블 기법의 종류
    1. 보팅
    2. 배깅, 페이스팅
    3. 랜덤 포레스트
    4. 부스팅
    5. 스태킹


2. 앙상블 기법의 종류

2.4 부스팅 (Boosting)

부스팅

여러 모델을 연결하여 강한 모델을 만드는 앙상블 기법을 말한다

즉, 앞의 모델을 뒤의 모델이 보완하면서 더 좋은 모델을 만들어 내는 것이다

 

이러한 부스팅에는 에이다 부스트 AdaBoost와 그레이디언트 부스팅 Gradient boosting이 있다

 

2.4.1 에이다 부스트 AdaBoost

에이다 부스트

에이다 부스트는 앞의 모델이 (이전모델) '과소적합' 했던 훈련 샘플의 가중치를 높여

학습해 나가는 앙상블 기법이다

 

예를들어 설명하면 모델을 만들 때 먼저 알고리즘이 기반이 되는 첫 번째 모델을 훈련세트로 훈련하고

예측을 만들어낸다. 그런 다음 알고리즘이 잘못 분류된 훈련 샘플의 가중치를 상대적으로 높여

두번째 모델에서 업데이트된 가중치를 사용하여 다시 예측을 만들어 내고

계속해서 이러한 가중치를 업데이트 하는 방식으로 진행된다

에이다 부스트 가중치 과정 코드 (구현) :
stackoverflow.com/questions/55318330/why-is-the-error-of-my-adaboost-implementation-not-going-down
*경사하강법과 비슷한 과정으로 진행
차이점 : 경사하강법은 모델의 파라미터를 수정해나가지만 부스팅은 모델을 추가해 나간다

*모든 훈련이 마치면 배깅이나 페이스팅과 같은 방식을 통해 예측을 만들어낸다. 
하지만, 이들은 연속된 학습 기법이기 때문에 모델 마다 다른 가중치를 적용한다

(연속된 학습 기법의 중요한 단점 = 각 예측기는 이전 예측가 학습 및 평과된 이후에 학습 될 수 있기 때문에 병렬화가 어렵다. 따라서 확장성이 높지 않다)

모델의 가중치를 수정해 나가는 과정

<수정 과정>

  1.  각 샘플 가중치 W**(i)는 초기에 1/m로 초기화
  2. 첫 번째 모델 학습이후, 가중치가 적용된 에러율 r이 훈련 세트에 대해 계산 (전체 가중치 총합에 대한 예측이 틀린 가중치 합의 비율) - (B)식
  3. 그런다음 모델에 대한 가중치를 계산 - (C)식  [모델이 정확할 수록 가중치가 더 높아짐, 무작위로 예측하는 정도(약50%이하) 가중치가 0에 가깝고 그것도 나쁘면 음수로]
  4. 그리고 에이다부스트 알고리즘식(D)를 통해서 샘플의 가중치를 업데이트, 잘못 분류된 샘플의 가중치가 증가
  5. 마지막으로 모든 샘플의 가중치를 정규화 
  6. 지정된 모델 수에 도달하거나 완벽한 모델이 만들어지면 중지하고, 각 모델의 예측과 각 모델의 가중치를 곱한다음 합하여 가중치 합이 가장 큰 클래스가 예측 결과가 된다

[코드]

from sklearn.ensemble import AdaBoostClassifier

ada_clf = AdaBoostClassifier(
	DecisionTreeClassifier(max_depth=1), n_estimators=200,
    algorithm="SAMME.R", learning_rate=0.5)
    
ada_clf.fit(X_train, y_train)

에이다 부스트도 sklearn에 구현되어 있다

여기서 algorithm의 매개변수에는 'SAMME.R'과 'SAMME'가 있는데 SAMME는 하드보팅과 비슷하면 SAMME.R은 소프팅 보팅과 비슷하게 확률에 기반하여 예측한다, 보팅과 비슷하게 SAMME.R이 일반적으로 성능이 더 좋다

 

 


2.4.2 그레이디언트 부스팅 Gradient Boosting

그래이디언트 부스팅, 줄여서 GBM으로 불리는 기법은 현재 머신러닝에서 가장좋은 성능을 내고 있는 기법

XGboost, LGBM, CatBoost등 머신러닝 대회에서 상위권을 차지하고 있는 대부분의 모델이 그레이디언트 부스팅 기법을 적용한 모델이다

 

그레이디언트 부스팅도 에이다부스트 처럼 이전 모델의 오차를 보정하도록 예측기를 순차적으로 추가한다

그러나 에이다부스트가 샘플의 가중치를 수정한다면 그레이디언트 부스팅은 이전 모델이 만든 잔여 오차에 새로운 모델을 학습시킨다

 

즉, 데이터 샘플링 없이 y값 즉, 목표값을 수정해서 이전모델이  예측하지 못한 예측을 예측하는 방법

 

 

Gradient Boosting from scratch

Simplifying a complex algorithm

blog.mlreview.com

 

 

단점 : 학습 데이터 셋에 과적합될 가능성이 높다

따라서 다양한 규제를 활용해 과적합을 피하는 것이 중요하다

 

[코드]

 

from sklearn.tree import DecisionTreeRregressor

tree_reg1 = DecisionTreeRregressor(max_depth=2)
tree_reg1.fit(X,y)

y2 = y - tree_reg1.predict(X)
tree_reg2 = DecisionTreeRregressor(max_depth=2)
tree_reg2.fit(X, y2)

....

y_pred = sum(tee.predict(X_new) for tree in (tree_reg1, tree_reg2 .....))

직접 구현한 그레디언트 부스팅 과정 

from sklearn.ensemble improt GradientBoostingRegressor

gbrt = GradientBoostingRegressor(max_depth = 2, n_estimators=3, learning_rate = 1.0)
gbrt.fit(X, y)


#subsample 하이퍼 파라미터 -> 확률적 그레이디언트 부스팅

그레이디언트 부스팅도 sklearn에 구현되어 있다 

여기서 subsample 하이퍼 파라미터를 추가해주면(0~1) 그 만큼 확률적 그레이디언트 부스팅을 할 수 있다

 

 

그레디언트 부스팅을 활용한 대표적 모델 (성능좋은)
1. XGBoost (extra gredient boost model)
https://wooono.tistory.com/97
2. LGBM(light gredient boost model)
https://nicola-ml.tistory.com/51
3. catboost
https://julie-tech.tistory.com/119

 


2.5 스태킹(Stacking)

앞에서 살펴본 모델들은 마지막 예측을 만들때 하드 보팅이나 소프트 보팅 같은 간단한 함수를 활용해서 예측을 만들었다

그러나 간단한 함수를 사용하는 대신에 모델을 활용해서 최종 예측을 하는 방법이 등장했는데 이걸 '스태킹'이라고 한다

 

캐글이나 데이콘 같은 대회에서 조금더 성능을 올리기 위해서 사용된다 (드라마틱한 변화는 없다)

 

방법은 간단하다

각 모델의 예측을 활용해서 새로운 X_train을 만든다

그리고 이렇게 만들어진 X_train을 통해서 y_train을 예측하는 것이다

 

[코드]

from sklearn.ensemble import StackingClassifier
from catboost import CatBoostClassifier
from lightgbm import LGBMClassifier
from xgboost import XGBClassifier 
from sklearn.ensemble import RandomForestClassifier



catc =  CatBoostClassifier(**cat_best_param)
lgbc =  LGBMClassifier(**lgb_best_param)
xgc = XGBClassifier(**xgboost_best_param)
rfc = RandomForestClassifier(**rf_best_param)

#메타모델 지정
model1 = [('cat', catc), ('lgb', lgbc), ('xgb', xgc), ('rfc', rfc)]
model2 = catc

stacking_model = StackingClassifier(estimators=model1, final_estimator=model2)
stacking_model.fit(X_train, y_train)

책에서는 스태킹이 sklearn에 없다고 하는데 추가되었다

여기서 각 모델을 지정해주고 모델의 파라미터를 설정해준다

그리고 이를 model1 과 model2로 묶는데 

model1은 각 모델의 예측을 뽑아내서 새로운 X_train을 만들어낸다 

그리고 난 후 modl2의 모델로 최종예측을 한다

(파라미터로 cv 교차검증을 하면 더 성능이 올라간다)

그리고 model1 같은 경우 3개 이상의 모델로 구성해줘야 어느 정도의 성능 개선을 볼 수 있다

 

단점 : 과적합의 위험이 높음