외로운 Nova의 작업실

앙상블 기법 본문

AI/machine-learning

앙상블 기법

Nova_ 2023. 11. 3. 18:03

- 앙상블

앙상블 기법이란 여러개의 분류 모델을 조합해서 더 나은 성능을 내는 방법입니다. 각 분류 모델의 값을 더해서 가장 최적의 값을 도출하는 기법입니다.

 

- 배깅

배깅은 마치 상당히 연주하기 힘든 바이올린 연주곡을 두 세명의 초급 바이올린 연주자가 나누어 연주함으로써 한명의 중급 바이올린 연주자가 연주하는 것보다 더 나은 연주를 할 수 있는 것과 유사합니다. 의사결정 트리는 과대적합되기 쉽다는게 단점인데 이는 편향적이라는 의미입니다. 

 

배깅은 한가지 분류 모델을 여러개 만들어서 서로 다른 학습 데이터로 학습시킨 후(부트스트랩), 동일한 테스트 데이터에대한 서로다른 예측값을 투표로 통해(어그리게이팅) 가장 높은 예측값으로 최종 결론을 내리는 기법입니다. 즉, 의사결정 트리를 일부러 편향적인 모델을 여러개 만들어두고 하나의 질문에 여러개의 모델의 값을 산출해서 가장 높은 예측값을 최종 도출값으로 낸다는 것입니다.

 

- 부트스트랩

부트스트랩은 데이터를 조금은 편향되도록 샘플링 하는 기법입니다. 예시로 1부터9까지중에 손글씨를 보고 무슨 숫자인지 알아맞추는 모델을 만든다고 할때 부트스트랩 기법을 사용해서 여러개 의사결정 트리를 만들게 되면 아래와 같습니다.

 

- 어그리게이팅

어그리게이팅은 여러 분류 모델이 예측한 값들을 조합해서 하나의 결론을 도출하는 과정입니다. 결론은 투표를 통해 결정합니다.

 

<하드보팅>

하드 보팅은 선거철에 하는 투표와 동일합니다. 부트스트랩에서 만든 모델의 도출값을 예시로 들어보겠습니다.

 

도출값이 7이 4개이기때문에 최종 도출값은 7이 됩니다.

 

<소프트 보팅>

소프트 보팅은 하드 보팅보다 더 정교한 투표 방식으로 모든 분류값의 확률을 리턴하고 모두 더한 값을 점수로 사용해 최대 점수를 가진 불류값을 결론으로 도출합니다. 아까 만든 의사결정 트리로 예시를 보자면 아래와 같습니다.

 

하나의 손글씨에대해 의사결정 트리1은 1이라고 0.9로 예측, 2라고 0.1로 예측하고 있습니다. 그리고 1에대한 6개의 모델의 총 합산 확률은 1.3이 됩니다. 이중에 7에대한 합산값이 3.4로 가장 높으므로 최종 도출값은 7로 될 것입니다.

 

- 랜덤 포레스트

랜덤 포레스트는 바로 여러 의사결정 트리를 배깅해서 예측을 실행하는 모델입니다. 배깅을 통해 의사결정 트리는 많은 개선을 이루었고 여러개의 나무들이 모여 있다는 개념에서 랜덤 포레스트라는 이름이 생겨났습니다. 

 

의사결정 트리에서는 최적의 특징으로 트리를 분기하는 반면, 랜덤 포레스트는 각 노드에 주어진 데이터를 샘플링해서 일부 데이터를 제외한 채 최적의 특징을 찾아 트리를 분기합니다. 이러한 과정에서 랜덤 포레스트는 또 한번의 모델의 편향을 증가시켜 과대적합의 위험을 감소시킵니다.

 

- 부스팅

배깅과 함께 각광받는 앙상블 기법인 부스팅에대해 알아보겠습니다. 부스팅 역시 여러개의 분류기(AI 모델)을 만들어 투표를 통해 예측값을 결정한다는 측면에서 배깅과 동일하지만 배깅은 서로 다른 알고리즘에 기반한 여러 분류기를 병렬적으로 학습하는 반면 부스팅은 서로 같은 알고리즘의 분류기를 순차적으로 학습해서 여러개의 분류기로 만든 후 테스트할 때 가중 투표를 통해 예측값을 결정합니다.

 

<순차적 학습>

가령 인물 사진 안에 있는 인물을 보고 남자 또는 여자로 분류하는 의사결정 트리를 부스팅할 경우, 먼저 첫번째 의사결정 트리를 학습합니다. 테스트 결과, 남자 분류가 미흡할 경우 남자 학습 데이터를 보강한 후 두번째 의사결정 트리를 학습합니다. 그리고 두 번째 의사결정 트리의 테스트 결과에 따라 학습 데이터를 보강해서 세번째 의사결정 트리를 학습합니다.

이처럼 부스팅은 순차적으로 학습 데이터를 보강하며 동일한 알고리즘의 분류기를 여러개 만드는 과정을 가집니다.

 

<가중 투표>

가중 투표는 예를 들어 사원 5명이 회식장소로 클럽을 가자고했찌만 부장님 3명이 삼겹살을 먹으러가자고 했을떄 삼겹살로 회식이 결정되는 것과 같습니다.

가령 아까 만든 분류기가 이러한 도출값을 냇을때 가중 투표 계산을 하면 아래처럼 됩니다.

 

남자 = 0.4 + 0.5

여자 = 0.95

 

따라서 여자가 계산값이 높기때문에 여자가 최종 도출됩니다.

 

소프트 보팅을 하면 아래와 같게됩니다.

 

- 실습

실습은 단일 모델들을 앙상블해서 투표를 통해 더 나은 예측을 해보겠습니다.

from sklearn import datasets
from sklearn import tree
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.ensemble import VotingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

#손글씨 데이터 로드
mnist = datasets.load_digits()
features, labels = mnist.data, mnist.target
X_train,X_test,y_train,y_test=train_test_split(features,labels,test_size=0.2)

#단일 모델들 측정
dtree = tree.DecisionTreeClassifier(
    criterion="gini", max_depth=8, max_features=32,random_state=35)

dtree = dtree.fit(X_train, y_train)
dtree_predicted = dtree.predict(X_test)

knn = KNeighborsClassifier(n_neighbors=299).fit(X_train, y_train)
knn_predicted = knn.predict(X_test)

svm = SVC(C=0.1, gamma=0.003,
          probability=True,random_state=35).fit(X_train, y_train)
svm_predicted = svm.predict(X_test)

print("[accuarcy]")
print("d-tree: ",accuracy_score(y_test, dtree_predicted))
print("knn   : ",accuracy_score(y_test, knn_predicted))
print("svm   : ",accuracy_score(y_test, svm_predicted))

SVM이 가장 높은 정확도를 보이는 것을 알 수 있습니다. 이제 보팅을 통해 정확도를 계산해보겠습니다.

 

#하드보팅
voting_clf = VotingClassifier(estimators=[
    ('decision_tree', dtree), ('knn', knn), ('svm', svm)], 
    weights=[1,1,1], voting='hard').fit(X_train, y_train)
hard_voting_predicted = voting_clf.predict(X_test)
accuracy_score(y_test, hard_voting_predicted)

단일 모델보다는 앙상블한 모델의 정확도가 더 높습니다.

 

#소프트보팅
voting_clf = VotingClassifier(estimators=[
    ('decision_tree', dtree), ('knn', knn), ('svm', svm)], 
    weights=[1,1,1], voting='soft').fit(X_train, y_train)
soft_voting_predicted = voting_clf.predict(X_test)
accuracy_score(y_test, soft_voting_predicted)

소프트보팅이 하드보팅보다 정확도가 낮습니다.

#시각화
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline

x = np.arange(5)
plt.bar(x, height= [accuracy_score(y_test, dtree_predicted),
                    accuracy_score(y_test, knn_predicted),
                    accuracy_score(y_test, svm_predicted),
                    accuracy_score(y_test, hard_voting_predicted),
                    accuracy_score(y_test, soft_voting_predicted)])
plt.xticks(x, ['decision tree','knn','svm','hard voting','soft voting']);

단일모델보다 앙상블 모델들이 정확도가 조금은 더 높은 것을 확인할 수 있습니다. 하지만 현실에서는 단일 모델들이 정확도가 더 높을 수 있습니다. 따라서 본인의 상황에 맞게 여러 검증 과정을 거쳐 가장 성능이 좋은 모델을 선택하는 것이 바람직합니다.

Comments