앙상블 학습(ensemble learning)으로 알고리즘 성능 개선하기(1) - Voting
Kaggle의 상위 솔루션들만 봐도 알겠지만, 단일 모델로는 어느 정도 성능을 극으로 끌어올리기는 한계가 있습니다. 그렇기 때문에 거의 모든 상위권에 랭크되는 솔루션들을 살펴보면 앙상블 학습(emsemble learning)으로 랭크를 올리는 모습을 볼 수 있습니다. 이번 포스팅에서는 앙상블 학습의 종류와 종류별 차이, 그리고 그에 따른 활용도에 대하여 적어볼까 합니다.
Ensemble Learning이란?
앙상블이란 단어를 wiki에서 검색해보면 다음과 같이 나옵니다.
통계역학에서, 어떤 계의 앙상블(ensemble)이란 그 계와 동등한 계의 모음을 말한다.
쉽게 말하면, 비슷한 무리들의 집합이라고 생각하시면 됩니다.
즉, 우리는 단일 모델에서 나오는 성능의 결과를 기대하는 것이 아니라,
여러 개의 단일 모델들의 평균치를 내거나, 투표를 해서 다수결에 의한 결정을 하는 등 여러 모델들의 집단 지성을 활용하여 더 나은 결과를 도출해 내는 것에 주 목적이 있습니다.
집단 지성을 활용하는 방법, 즉 앙상블 기법에는 다양한 방법이 있습니다.
- Voting (투표) - 투표를 통해 결과 도출
- Bagging - Bootstrap Aggregating (샘플을 다양하게 중복 생성)
- Boosting - 이전 오차를 보완하며 가중치 부여
- Stacking- 여러 모델을 기반으로 meta 모델
사실 앙상블 기법은 말 그대로 하나의 기법/방법론 적인 부분이 있어서 다양한 방식들이 추가로 더 있을 수 있습니다. 하지만, 위에 언급한 4가지가 대표적인 앙상블 기법이며 이미 sklearn 라이브러리에도 구현된 기법들입니다.
그럼 이제 하나씩 살펴보도록 하겠습니다.
Voting
Voting은 단어 뜻 그대로 투표를 통해 결정하는 방식입니다. Voting은 Bagging과 투표방식이라는 점에서 유사하지만, 다음과 같은 큰 차이점이 있습니다.
- Voting은 다른 알고리즘 model을 조합해서 사용합니다.
- Bagging은 같은 알고리즘 내에서 다른 sample 조합을 사용합니다.
즉, voting은 서로 다른 알고리즘이 도출해 낸 결과물에 대하여 최종 투표하는 방식을 통해 최종 결과를 선택합니다. voting은 hard vote와 soft vote로 나뉘게 되는데, hard vote는 결과물에 대한 최종 값을 투표해서 결정하고, soft vote는 최종 결과물이 나올 확률 값을 다 더해서 최종 결과물에 대한 각각의 확률을 구한 뒤 최종 값을 도출해 냅니다.
코드로 작성해 보자면 다음과 같이 구현할 수 있습니다.
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier, AdaBoostClassifier, ExtraTreesClassifier, BaggingClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from xgboost import XGBClassifier
from lightgbm import LGBMClassifier
from sklearn.neighbors import KNeighborsClassifier
from sklearn.linear_model import LogisticRegressionCV, RidgeClassifier
# VotingClassifier
from sklearn.ensemble import VotingClassifier
# ensemble 할 model 정의
models = [
('ada', AdaBoostClassifier()),
('bc', BaggingClassifier()),
('etc',ExtraTreesClassifier()),
('gbc', GradientBoostingClassifier()),
('rfc', RandomForestClassifier()),
('knn', KNeighborsClassifier()),
('svc', SVC(probability=True)),
('xgb', XGBClassifier()),
('lgbm', LGBMClassifier()),
('dtc', DecisionTreeClassifier()),
('lr', LogisticRegressionCV()),
('ridge', RidgeClassifier()),
]
# hard vote
hard_vote = VotingClassifier(models, voting='hard')
hard_vote_cv = cross_validate(hard_vote, x_train, y_train, cv=k_fold)
hard_vote.fit(x_train, y_train)
# soft vote
soft_vote = VotingClassifier(models, voting='soft')
soft_vote_cv = cross_validate(soft_vote, x_train, y_train, cv=k_fold)
soft_vote.fit(x_train, y_train)
Hard Vote
classification을 예로 들어 보자면, 분류를 예측한 값이 1, 0, 0, 1, 1 이었다고 가정한다면 1이 3표, 0이 2표를 받았기 때문에 Hard Voting 방식에서는 1이 최종 값으로 예측을 하게 됩니다.
Soft Vote
soft vote 방식은 각각의 확률의 평균 값을 계산한다음에 가장 확률이 높은 값으로 확정짓게 됩니다.
가령 class 0이 나올 확률이 (0.4, 0.9, 0.9, 0.4, 0.4)이었고, class 1이 나올 확률이 (0.6, 0.1, 0.1, 0.6, 0.6) 이었다면,
class 0이 나올 최종 확률은 (0.4+0.9+0.9+0.4+0.4) / 5 = 0.44, class 1이 나올 최종 확률은 (0.6+0.1+0.1+0.6+0.6) / 5 = 0.4 가 되기 때문에 앞선 Hard Vote의 결과와는 다른 결과 값이 최종 으로 선출되게 됩니다.
Tip
보통 대회에서는 Hard Vote보다는 Soft Vote 방식이 더 합리적인 방법이라는 것이 대세입니다. 실제 성능결과도 Soft Vote 방식이 훨씬 더 잘 나와서이겠죠?
댓글남기기