본문 바로가기
Machine Learning/scikit-learn

[앙상블] 앙상블의 개념과 보팅(하드보팅 vs. 소프트 보팅)

by ISLA! 2023. 8. 22.

 

 

앙상블 학습이란?

  • 여러 개의 분류기(Classifier)를 생성하고 그 예측을 결합함으로써 보다 정확한 최종 예측을 도출
  • 단일 분류기보다 신뢰성이 높은 예측값을 얻는 것
  • 대부분의 정형 데이터 분류 시에는 앙상블이 뛰어난 성능을 보임
  • 결정 트리 알고리즘의 단점(과적합 위험)을 극복하여 편향-분산 트레이드오프의 효과를 극대화함

 

앙상블 학습의 유형

 

보팅과 배깅 비교

 

  • 보팅 : 서로 다른 알고리즘을 가진 분류기를 결합
    • 소프트 보팅과 하드 보팅이 있음
    • 일반적으로 소프트 보팅이 적용됨
  • 배깅 : 분류기가 모두 같은 유형의 알고리즘 기반이지만, 데이터 샘플링을 다르게 하여 학습 ➡ 그 후, 보팅
    • 대표적인 배깅 방식 : 랜덤 포레스트 알고리즘
    • 배깅은 개별 분류기에 할당된 학습 데이터를 원본 학습데이터에서 추출 ➡ 이 방식을 부트스트래핑 분할이라고 함
    • 교차 검증이 데이터 세트의 중첩을 허용하지 않지만, 배깅 방식은 중첩을 허용하여 데이터 추출
    • 대부분 결정트리 알고리즘 기반
  • 부스팅
    • 여러개의 분류기가 순차적으로 학습을 수행하되,
    • 앞에서 학습한 분류기가 예측이 틀린 데이터에 대해서는 올바르게 예측할 수 있도록 다음 분류기에게 가중치를 부여하면서 학습과 예측 진행
    • 예측 성능이 뛰어나 앙상블 학습을 주도
    • 대표적인 모듈 ➡ 그래디언트 부스트, XGBoost, LightBGM 이 있음
    • 대부분 결정트리 알고리즘 기반
  • 스태킹
    • 여러 가지 다른 모델의 예측 결괏값을 다시 학습 데이터로 만들어서 다른 모델(메타 모델)로 재학습시켜 결과를 예측

 


보팅

 

  • 하드 모팅은 예측 결괏값들 중 다수의 분류기가 결정한 예측값을 최종 보팅 결괏값으로 선정 (다수결 개념)
  • 소프트 보팅은 분류기들의 레이블 값 결정 확률을 모두 더하고 이를 평균해서 이들 중 확률이 가장 높은 레이블 값을 최종 보팅 결괏값으로 선정
  • 하드 보팅보다 소프트 보팅이 예측 성능이 일반적으로 더 좋아서 많이 사용됨

 


📦 보팅 예제 : 위스콘신 유방암 데이터 세트 활용

  • 사이킷런은 보팅 방식의 앙상블을 구현한 VotingClassifier 클래스를 제공
  • 예제 코드로 보팅 이해

 

데이터 불러오기

import pandas as pd
from sklearn.ensemble import VotingClassifier
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 데이터 불러오기
cancer = load_breast_cancer()

data_df = pd.DataFrame(cancer.data, columns = cancer.feature_names)
data_df.head(1)

 

모델 학습

  • 로지스틱 회귀와 KNN 기반으로 모델 학습 시킴
  • 개별 모델을 소프트 보팅 기반 앙상블 모델로 구현
    • estimators = 개별 모델을 튜플로 묶어 리스트로 지정
    • voting = 'soft'
lr_clf = LogisticRegression(solver='liblinear')
knn_clf = KNeighborsClassifier(n_neighbors=8)

# 개별 모델을 소프트 보팅 기반의 앙상블 모델로 구현
vo_clf = VotingClassifier(estimators = [('LR', lr_clf), ('KNN', knn_clf)], voting='soft')

# 훈련데이터, 테스트데이터 분리
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size = 0.2, random_state = 1)

# 학습, 예측, 평가
vo_clf.fit(X_train, y_train)
pred = vo_clf.predict(X_test)
print('Voting 분류기 정확도: {0:.4f}'.format(accuracy_score(y_test , pred)))

정확도 확인

 

  • 반복문을 사용하여 개별 모델의 학습/예측/평가 시행
  • 모델.__class__.__name__ : 모델의 이름을 가져오는 바업ㅂ
classifiers = [lr_clf, knn_clf]
for classifier in classifiers:
    classifier.fit(X_train, y_train)
    pred = classifier.predict(X_test)
    class_name = classifier.__class__.__name__  # 각 모델의 이름 가져오기
    
    print('{0} 정확도: {1:.4f}'.format(class_name, accuracy_score(y_test , pred)))

정확도 확인

  • 보팅을 사용한 경우와 , 개별 모델들의 정확도를 비교
  • 일반적으로 보팅을 사용한 경우의 평가 수치가 더욱 높아짐(항상 예측 성능이 향상되는 것은 아님!)
728x90