Model Ensemble
- 여러 모델들을 함께 사용하여 성능을 올린다.
- 앙상블 기법에는 voting, bagging, boosting, stacking 등이 있다.
Voting
1) 개요
- 다른 종류의 모델들의 예측값을 합쳐 최종 결과를 도출해내는 방법이다.
- continuous outputs : combine it by averaging
- class label outputs : combine it by voting
- Voting 종류는 크게 hard, soft, weighted로 나뉜다.
2) Hard voting
- Unanimous voting : 만장일치일 때만 선택한다.
- Majority voting : 제일 많이 나온 것을 선택한다.
Ensemble(ˆy)=argmax(n∑j=1I(ˆyj=i),i∈(0,1))
3) Soft voting
- 각 class별로 모델들이 예측한 확률의 평균 값을 계산하여 가장 높은 class 선택
Ensemble(ˆy)=argmax(1nn∑j=1P(y=i)),i∈(0,1))
4) Weighted voting
- 각각의 모델별로 class에 대한 가중치를 준다.
-아래 식은 training accuracy를 사용하여 가중평균을 계산한 방법이다.
Ensemble(ˆy)=argmax(∑nj=1(TrainAccj)⋅I(ˆyj=i)∑nj=1(TrainAccj)),i∈(0,1))
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import Pipeline
import numpy as np
clf1 = LogisticRegression(solver = 'liblinear', penalty = 'l2', C = 0.001, random_state = 1)
clf2 = DecisionTreeClassifier(max_depth = 1, criterion = 'entropy', random_state = 0)
clf3 = KNeighborsClassifier(n_neighbors = 1, p = 2, metric = 'minkowski')
pipe1 = Pipeline([['sc', StandardScaler()], ['clf', clf1]])
pipe3 = Pipeline([['sc', StandardScaler()], ['clf', clf3]])
# Votingclassifier / votingregressor
from sklearn.ensemble import VotingClassifier
models = [pipe1, clf2, pipe3]
hard_vote = VotingClassifier(models, voting='hard')
asdf = cross_val_score(estimator = hard_vote, X = X_train, y= y_train,
cv = 10, scoring = 'roc_auc')
hard_vote.fit(X_train, y_train)
Bagging (Bootstrap Aggregating)
1) 개요
- 각각의 bootstrap sample로 부터 생성된 모델을 합침
- voting은 모델의 종류가 다양하지만 bagging은 동일 알고리즘을 여러 개 사용한다.
- 대표적으로 Randomforest가 있다. (sjpyo.tistory.com/41?category=956366)
Random Forest
Random Forest (결정트리) 1) 개요 - decision tree의 ensemble로 decision tree들의 예측을 종합한다. - decision tree의 low computational complexity (모델 구축 속도), nonparametric 특성으로 base 모델로..
sjpyo.tistory.com
2) Bootstrap
- sampling 방법으로 각 모델은 다른 훈련 데이터셋을 이용
- 복원추출(같은 샘플이 여러 개 있을 수 있다)을 통해 원래 데이터의 수와 동일한 크기를 sampling
- 이론적으로 1 개의 샘플이 한번도 sampling 되지 않을 확률
p=(1−1N)N→limN→∞(1−1N)N=e−1=0.368
3) Aggregating
- 위의 voting 방식을 사용해 합산한다.
Random subspace
1) 원래 변수들 중에서 모델 구축에 사용할 입력 변수를 무작위 선택 (모든 변수보다 적은 변수 선택)
2) 선택된 입력 변수 중 분할될 변수 선택
3) full-grown tree가 될 때까지 반복
ex) 변수 1, 2, 3, 4, 5번이 있을 때, (1)에 의해 2, 3, 5번이 무작위로 선택됐다. 이때 선택된 3가지 중 impurity index가 가장 이상적
인 변수를 선택하고 이를 반복한다.
from sklearn.ensemble import BaggingClassifier
tree = DecisionTreeClassifier(criterion = 'entropy', random_state = 1, max_depth = None)
bag = BaggingClassifier(base_estimator = tree, n_estimators = 500, max_samples = 1.0,
max_features = 1.0, bootstrap = True,
bootstrap_features = False, n_jobs = -1, random_state = 1)
Boosting
1) 개요
- weak learner (약한 학습기) 라는 매우 간단한 분류기이다.
- 순차학습을 통해 잘못 분류된 샘플에 가중치를 부여해 오차를 줄여나간다.
- 순차적으로 모델을 구축하기 때문에 순서가 매우 중요하다.
- 대표적으로 AdaBoost 알고리즘이 있으며, 이후 Xgboost, LightGBM, Catboost 등이 등장했다.
2) Adaboost (Adaptive Boosting)
- training error 크면 가중치를 높이고, 작으면 가중치를 낮춰 오분류한 관측치에 무게를 둔다.
- 이를 기반으로 다음 단계에서 사용할 dataset을 구성하고 이를 반복하여 최종 결과를 예측한다.
- AdaBoost algorithm

(1) impose equal weight initially
Wi=1n,i=1,2,...,n
(2) find h(x) that minimizes L (weighted loss function); 아래의 예는 3개 오분류한 경우
Lj=∑ni=1WiI(yi≠hj(x))∑ni=1Wi=0.1×30.1×10=0.3
(3) calculate each classes' weights
a1=log(1−LjLj)=log(1−0.30.3)=≈0.37
(4) update samples weights
Wc=WieajI(yi≠h1(x))=0.1e0.37×0=0.1
Wnc=0.1e0.37×1=0.14
(5) step 2로 돌아가서 다시 수행한다.
(6) Final step
h(x)=sign[m∑i=1ajhj(x)]
Indicator function : if x true -> 1, if x false -> 0
I(yi≠hi(x))
- 코드 예시
from sklearn.ensemble import AdaBoostClassifier
tree = DecisionTreeClassifier(criterion = 'entropy',
random_state =1, max_depth = 1)
ada = AdaBoostClassifier(base_estimator = tree, n_estimators = 500,
learning_rate = 0.1, random_state = 1)
ada = ada.fit(X_train, y_train)
3) GBM (Gradient Boosting Machines)
- base 모델로 decision tree 사용
- 순차적으로 residual (y - 예측y)값을 다시 fitting해가며 줄여가는 방식이다.


- residual & gradient
L=12n∑i=1(yi−f(xi))2
Gradient⇒∂L∂f(xi)=−(yi−f(xi))=residual

- 코드 예시
from sklearn.ensemble import GradientBoostingClassifier
gbrt = GradientBoostingClassifier(n_estimators = 20, random_state = 42)
gbrt.fit(X_train, y_train)
gbrt_train_score = gbrt.score(X_train, y_train)
gbrt_test_score = gbrt.score(X_test, y_test)
참고
머신러닝 교과서 (길벗)
machinelearningmastery.com/voting-ensembles-with-python/
고려대 김성범 교수님 유튜브 www.youtube.com/channel/UCueLU1pCvFlM8Y8sth7a6RQ
medium.com/mlreview/gradient-boosting-from-scratch-1e317ae4587d