1.11. Ensembles: Gradient boosting, random forests, bagging, voting, stacking

1. Voting Classifier

다른 머신 러닝 분류기를 결합하고 다수결 투표나 평균 예측 확률(소프트 투표)을 사용하여 클래스 레이블을 예측한다 . 이 분류기는 개별적인 약점을 균형 잡기 위해 동등하게 성능이 좋은 모델 집합에 유용할 수 있다.

1.1 Voting = “hard”

특정 샘플에 대해 예측된 클래스 레이블은 각 개별 분류기가 예측한 클래스 레이블 중 가장 많이 나온 클래스 레이블이 최종 선택된다.

ex.

최종 클래스 레이블은 “클래스 1”이다.

→ 이유: 각 개별 분류기가 예측한 클래스 레이블 중 클래스 1이 가장 많기 때문이다.

from sklearn import datasets
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.ensemble import RandomForestClassifier
from sklearn.ensemble import VotingClassifier

iris = datasets.load_iris()
X, y = iris.data[:, 1:3], iris.target

clf1 = LogisticRegression(random_state=1)
clf2 = RandomForestClassifier(n_estimators=50, random_state=1)
clf3 = GaussianNB()

eclf = VotingClassifier(
    estimators=[('lr', clf1), ('rf', clf2), ('gnb', clf3)],
    voting='hard')

for clf, label in zip([clf1, clf2, clf3, eclf], ['Logistic Regression', 'Random Forest', 'naive Bayes', 'Ensemble']):
    scores = cross_val_score(clf, X, y, scoring='accuracy', cv=5)
    print("Accuracy: %0.2f (+/- %0.2f) [%s]" % (scores.mean(), scores.std(), label)) 

1.2 Voting = “soft”

voting="soft" 는 예측 확률의 합의 argmax로 클래스 레이블을 반환한다.

매개변수를 통해 각 분류기에 특정 가중치를 할당할 수 있다. 가중치가 제공되면 각 분류기의 예측 클래스 확률이 수집되어 분류기 가중치에 곱해지고 평균화된다. 그런 다음 최종 클래스 레이블은 평균 확률이 가장 높은 클래스 레이블을 선택한다.

ex.

분류기 1학년 2학년 3학년
분류기 1 w1 * 0.2 w1 * 0.5 w1 * 0.3
분류기 2 w2 * 0.6 w2 * 0.3 w2 * 0.1
분류기 3 w3 * 0.3 w3 * 0.4 w3 * 0.3
가중 평균 0.37 0.4 0.23

최종 예측 클래스 레이블: 클래스 2

→ 이유: 평균 확률이 가장 높음

from sklearn.tree import DecisionTreeClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier

# classifiers
clf1 = DecisionTreeClassifier(max_depth=4)
clf2 = KNeighborsClassifier(n_neighbors=7)
clf3 = SVC(kernel='rbf', probability=True)
eclf = VotingClassifier(
				estimators=[('dt', clf1), ('knn', clf2), ('svc', clf3)], 
				voting='soft', weights=[2, 1, 2]
				)
# model training
clf1 = clf1.fit(X, y)
clf2 = clf2.fit(X, y)
clf3 = clf3.fit(X, y)
eclf = eclf.fit(X, y)