사이킷런 VotingClassifier(다수결 투표)
April 11, 2022, 11:26 p.m.
머신러닝에는 수많은 모델이 있고 그 모델들은 각각의 장단점이 있습니다. 이런 장단점을 보완하기 위해서 여러 모델을 동시에 훈련시켜 결합하는 앙상블 기법이 많이 사용되고 있습니다. 앙상블 기법을 사용하면 좋은 점은 개별 분류기의 단점을 보완할 수 있다는 것이고 모델을 여러개 사용하므로써 모델 하나가 분류 오차를 냈을 때 보다 여러개가 동시에 오차를 낼 확률이 적기 때문에 모델의 성능이 전체적으로 올라가게 됩니다. 이것은 이항분포를 생각하면 쉽습니다.
이번 포스트에서는 여러가지 머신러닝 모델을 결합해서 더 좋은 성능을 내는 앙상블 기법, 그중에서도 다수결 투표 기법을 사용해보겠습니다.
다수결 투표는 말 그대로 여러개의 분류기를 훈련 시킨 후 각 분류기의 예측을 종합하여 가장 많은 클래스를 결과로 도출하는 방식입니다. 사이킷런에서 VotingClassifier로 구현되어 있습니다. 바로 사용해 보겠습니다.
import numpy as np
import pandas as pd
from sklearn import datasets
iris = datasets.load_iris()
X, y = iris.data, iris.target
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, stratify=y)
학습할 데이터를 가져오고 테스트 셋과 훈련 셋으로 나누었습니다.
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import KernelPCA
from sklearn.linear_model import LogisticRegression
from sklearn.naive_bayes import GaussianNB
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import VotingClassifier
nb = make_pipeline(StandardScaler(), KernelPCA(n_components=2), GaussianNB())
lr = make_pipeline(StandardScaler(), KernelPCA(n_components=2), LogisticRegression(max_iter=10000, C=0.1))
dt = DecisionTreeClassifier(max_depth=2)
vc = VotingClassifier([('lr', lr), ('nb', nb), ('dt',dt)])
3개의 간단한 분류 모델을 파이프라인을 통해 전처리 포함해서 선언했고 이것을 VotingClassifier의 매개변수로 넣어주었습니다. 모델을 넣어줄 때는 ('모델이름', 모델)의 튜플이 담긴 리스트를 넣어주어야 합니다.
nb.fit(X_train, y_train)
lr.fit(X_train, y_train)
dt.fit(X_train, y_train)
vc = vc.fit(X_train, y_train)
비교를 위해 각각의 분류기를 모두 학습시켰습니다.
from sklearn.model_selection import cross_val_score
print(lr.score(X_test, y_test), nb.score(X_test, y_test), dt.score(X_test, y_test), vc.score(X_test, y_test))
그 다음 교차 검증을 통해 테스트 셋에서 각각의 분류기의 성능을 평가해보았습니다. 결과는 아래와 같습니다.
0.9809523809523809 0.9809523809523809 0.6666666666666666 0.9904761904761905
결과를 보면 알 수 있듯이, 각각의 분류기의 성능보다 Votingclassifier를 통해 결합한 모델의 성능이 좋은 모습을 볼 수 있네요.
또한 각각의 분류기가 잘 튜닝된 상태라면 VotingClassifier.predict_proba(X) 를 통해 각 클래스에 해당될 신뢰도 있는 확률을 얻어낼 수 도 있습니다.
이렇듯 Votingclassifier를 통해 모델을 결합하면 보다 더 좋은 성능을 기대할 수 있습니다. 그렇지만 튜닝해야할 하이퍼 파라미터도 많아지고 학습 시간, 추론 시간이 더 길어진다는 단점도 있습니다.
사이킷런 scikit-learn VotingClassifier