앙상블 : 프랑스어로 '함께, 동시에, 한꺼번에, 협력하여' 등을 의미하는 부사
1. 앙상블 학습이란?
앙상블 학습(Ensemble Learning)은 여러 개의 분류기를 생성하고, 그 예측을 결합함으로써 보다 정확한 예측을 도출하는 기법을 말합니다.
강력한 하나의 모델을 사용하는대신 보다 약한 모델 여러개를 조합하여 더 정확한 예측에 도움을 주는 방식입니다.
현실세계로 예를 들면, 어려운 문제를 해결하는데 한 명의 전문가보다 여러명의 집단지성을 이용하여 문제를 해결하는 방식을 앙상블 기법이라 할 수 있습니다.
2. 앙상블 학습 유형
앙상블 학습은 일반적으로 보팅(Voting), 배깅(Bagging), 부스팅(Boosting) 세 가지의 유형으로 나눌 수 있습니다.
- 보팅(Voting)
- 여러 개의 분류기가 투표를 통해 최종 예측 결과를 결정하는 방식
- 서로 다른 알고리즘을 여러 개 결합하여 사용
- 보팅 방식
- 하드 보팅(Hard Voting)
- 다수의 분류기가 예측한 결과값을 최종 결과로 선정
- 소프트 보팅(Soft Voting)
- 모든 분류기가 예측한 레이블 값의 결정 확률 평균을 구한 뒤 가장 확률이 높은 레이블 값을 최종 결과로 선정
- 하드 보팅(Hard Voting)
- 배깅(Bootstrap AGGregatING, Bagging)
- 데이터 샘플링(Bootstrap) 을 통해 모델을 학습시키고 결과를 집계(Aggregating) 하는 방법
- 모두 같은 유형의 알고리즘 기반의 분류기를 사용
- 데이터 분할 시 중복을 허용
- Categorical Data : 다수결 투표 방식으로 결과 집계
- Continuous Data : 평균값 집계
- 과적합(Overfitting) 방지에 효과적
- 대표적인 배깅 방식 : 랜덤 포레스트 알고리즘
- 부스팅(Boosting)
- 여러개의 분류기가 순차적으로 학습을 수행
- 이전 분류기가 예측이 틀린 데이터에 대해서 올바르게 예측할 수 있도록 다음 분류기에게 가중치(weight)를 부여하면서 학습과 예측을 진행
- 계속하여 분류기에게 가중치를 부스팅하며 학습을 진행하기에 부스팅 방식이라고 불림
- 예측 성능이 뛰어나 앙상블 학습을 주도
- 대표적인 부스팅 모듈 – XGBoost, LightGBM, SKlearn
- 보통 부스팅 방식은 배깅에 비해 성능이 좋지만, 속도가 느리고 과적합이 발생할 가능성이 존재하므로 상황에 따라 적절하게 사용해야 함.
정형 데이터 / 비정형 데이터
여태까지 사용했던 데이터들 (도미/빙어/와인 등..)은 길이,무게,높이 등 csv파일에 가지런한 데이터로 되어있었다. 이런 데이터들을 정형 데이터라고 부른다.[어떠한 구조로 되어있다는 뜻] CSV / XLSX 등에 저장하기 쉽다. 반대로 비정형 데이터는 책과 같은 텍스트 데이터, 사진 , 음악, 영상 등이 있다.
정형 데이터들을 다루는 데 가장 뛰어난 성과를 내는 알고리즘이 앙상블 학습 이라고한다.
그렇다면 비정형 데이터는 어떤 알고리즘을 사용해야할까? (+어떻게 정리?) > 7장
랜덤 포레스트 알고리즘
랜덤 포레스트는 앙상블 학습의 대표격으로, 안정적 성능을 자랑한다.
좋은 이유 ==> 1. 배깅의 이점을 살리고, 2. 변수를 랜덤으로 선택하는 과정을 추가함으로 개별나무들의 상관성을 줄여 예 측력이 좋기 때문
1 : 배깅 : 데이터 샘플링(Bootstrap) 을 통해 모델을 학습시키고 결과를 집계(Aggregating) 하는 방법
2 : 변수를 랜덤 으로 선택
랜덤 포레스트는 결정 트리를 랜덤하게 만들어 결정 트리의 숲을 만들고, 각 트리의 예측을 사용해 최종 예측을 만듦.
- 트리의 훈련 데이터를 랜덤하게 설정 : 부트스트랩 샘플 (노드 분할시 계속 전체 무작위로)
예측력이 좋은 이유 : 다른 알고리즘과 달리 변수들의 상관관계 확연히 줄어듦.개별 나무 분리할 때마다 계속해서 랜덤한 데이터가 뽑히므로!
와인 데이터셋으로 해보자
import numpy as np
import pandas as pd
from sklearn.model_selection train_test_split
wine = pd.read_csv('https://bit.ly/wine_csv_data')
data = wine[['alcohol','sugar','pH']].to_numpy()
target = wine['class'].to_numpy()
train_input, test_input, train_target, test_target = train_test_split(data,target, test_size=0.2, random_state=42)
cross_validate()으로 교차검증을 해보자!랜덤포레스트 기본 결정트리 개수 = 100개n_jobs = -1 (오래걸리니까?)
return_train_score = True : 검증점수 뿐만아니라 훈련 세트에 대한 점수도 같이 반환한다
(과대 /과소 파악하는데 쉬우므로)
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = corss_validate(rf, train_input, train_target,
return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.9973541965122431 0.8905151032797809
훈련세트에 과대적합
도수 / 당도 / pH
특성 중요도 < 단순 결정 트리에서는 0.123 / 0.868 / 0.00791 > 였다.!
rf.fit(train_input, train_target)
print(rf.feature_importances_)
[0.23167441 0.50039841 0.26792718]
랜덤 포레스트 알고리즘에서의 특성 중요도는 당도가 줄어들고 도수 pH가 모두 증가
>>>랜덤하게 선택하여 개별 나무들의 상관성이 줄어들었기 때문 ( 예측력 상승)<<<
OOB 샘플 (out of bag) 샘플
말그대로 사용되지 않고 남은 샘플을 의미,
이 샘플들을 이용해서 부트스트랩 샘플로 훈련한 트리를 평가할 수 있다!! ( 검증 세트의 역할과 비슷)
rf = RandomForestTreeClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score)
0.8934000384837406
엑스트라 트리
엑스트라 트리는 랜덤 포레스트와 비슷하게 동작한다.
차이점: 부트스트랩 샘플 사용 X , 결정트리를 만들 때 전체 훈련 세트를 사용한다. 대신 노드를 분할할 때 가장 좋은 분할을 찾는 것이 아니라 무작위로 분할한다. 기존의 결정 트리에서 splitter='random' 사용한것과 같.
성능은 낮아지지만 검증 세트의 점수를 높일 수 있다.(왜?) + 속도 빠르다 ( 기준이 랜덤) +
from sklearn.ensemble import ExtraTreesClassifier
et = ExtraTreesClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(et, train_input, train_target,
return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_scores']), np.mean(scores['test_score']))
0.9974503966084433 0.8887848893166506
비슷하다 (특성 많지않아서) 특성 중요도를 살펴보자.
ef.fit(train_input, train_target)
print(ef.feature_importances_)
[0.20183568 0.52242907 0.27573525]
오 비슷하다.
다음은 랜덤포레스트 / 엑스트라 트리와는 다른 앙상블 학습을 알아보자.
그레이디언트 부스팅
그레디언트 부스팅(Gradient boosting)
- 깊이가 얕은 결정 트리 ( 이전 트리의 오차를 보완해 나가는 방식)
- 경사하강법을 사용
- 분류- 로지스틱 손실 함수를 사용 / 회귀 - 평균 제곱 오차 함수를 사용
( 경사하강법 조금씩 이동 ) <=> ( 그레디언트 - 길이 얕은 트리)
https://www.youtube.com/watch?v=3CC4N4z3GJc
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(random_state=42)
scores = cross_validate(gb, train_input, train_target,
return_train_score = True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_scores']))
0.8881086892152563 0.8720430147331015
굿! 개수를 더 높여보자 (개수 500)
from sklearn.ensemble import GradientBoostingClassifier
gb = GradientBoostingClassifier(n_estimators= 500, learning_rate=0.2,random_state=42)
scores = cross_validate(gb, train_input, train_target,
return_train_score = True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_scores']))
0.9464595437171814 0.8780082549788999
특성 중요도
gb.fit(train_input,train_target)
print(gb.feature_importances_)
[0.15872278 0.68010884 0.16116839]
+새로운 매개변수 subsample : 트리 훈련에 사용할 훈련 세트 비율을 정함 (default=1 [전체])
subsample을 낮추면???? <<< 미니배치 경사 하강법과 비슷함 >>>
그레디언트 부스팅은 랜덤 포레스트보다 더 높은 성능! 하지만 속도 느리고 과적합 가능성 높다.
그레디언트 부스팅의 속도와 성능을 개선한 모델
히스토그램 기반 그레이디언트 부스팅
정형 데이터를 다루는 머신러닝 알고리즘 중 가장 인기가 높은 알고리즘이래.
입력 특성을 256개의 구간으로 나눈다. 따라서 노드를 분할할 때 최적의 분할을 빠르게 찾을 수 있다.
히스토그램 기반 그레디언트 부스팅은 256개의 구간 중에서 하나를 떼어 놓고 누락된 값을 위해서 사용한다.
따라서 입력에 누락된 특성이 있더라도 이를 따로 전처리할 필요가 없다! (왜?)
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target,
return_train_score=True)
print(np.mean(scores['train_score']),np.mean(scores['test_score']))
0.9321723946453317 0.8801241948619236
과대적합 더 억제하면서 그레디언트부스팅보다 성능이 좋다.
여기서 특성중요도는 feature_importnaces_가 아니라 permutation_importance 라고 한다.
from sklearn.inspection import permutatin_importance
hgb.fit(train_input,train_target)
result = permutation_importance(hgb, train_input,train_target,
n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)
[0.08876275 0.23438522 0.08027708]
n_repeats는 랜덤하게 섞을 횟수 (default=5)
성능을 확인해보자.
hgb.score(test_input,test_target)
0.8723076923076923
사이킷런 말고 그레디언트 부스팅 알고리즘을 쓰고싶다면 XGBoost 가 있다.
from XGBoost import XGBClassifier
xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target,
return_train_score=True)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.8824322471423747 0.8726214185237284
'머신러닝 & 딥러닝 기초 > 5장 - 트리 알고리즘' 카테고리의 다른 글
5 - 2 교차 검증과 그리드 서치 (0) | 2023.01.10 |
---|---|
5 - 1 결정 트리 (1) | 2023.01.09 |