1. Boosting 부스팅
핸즈온 머신러닝의 앙상블 (https://eumgill98.tistory.com/20)을 공부하다 보니
다른 앙상블 기법들은 이해하기 쉬웠으나
Boosting 부스팅이 조금 더 자세히 살펴볼 필요가 있다고 생각되어서
(수식적인 이해를 할 식들이 많다) Deep한 머신러닝의첫 번째 주제로 선택하게 되었다
이번 글에서는 Boosting 깊이 있게 살펴 보려고 한다
포괄적인 이해를 원한다면 위의 앙상블 포스팅 링크를 참조해주기를 바란다
1.1 AdaBoosting
오늘 알아볼 부스팅은 AdaBoosting이다
참고한 동영상 강의 : https://youtu.be/HZg8_wZPZGU
AdaBoosting은 Adaptive + Boosting으로 만들어진 단어로
약한 분류기(weak classifier)들이 상호보완적게 순차적으로 학습되어 이들의 조합이 최적의 예측을 만들어내는 상태를 모델로 결정하여 (loss가 가장 적은) 강한 분류기(strong classifier)를 만들어 내는 방법이다
여기서 약한 모델 (weak classifier)이란?
= 랜덤 보다 조금더 잘하는 모델을 의미하는데 즉, 50%보다 조금 더 높은 모델이다.
AdaBoosting의 진행과정을 살펴보면 경사하강법과 상당히 유사하다는 것을 알 수 있다
그러나 AdaBoosting과 경사하강법은 차이점이 존재하는데
이는 경사하강법의 경우 모델의 가중치를 수정해 나가지만 AdaBoosting의 경우는 모델을 추가함으로
정확성을 향상시킨다
(위의 사진은아래 과정을 시각화 해서 보여주는 사진이다)
또한 AdaBoosting의 핵심은 이전 모델이 약하게 학습한 데이터의 가중치를 조정하여서 더 강하게 학습하게 만드는 것이다
즉, 순차적은 모델들의 학습과정에서 과소적합된 데이터의 가중치를 증가시켜 그 다음모델에서는 조금 더 강하게 예측하게 만들어 나간다 (쉽게 말해서 오답노트를 활용해서 개선해 나가는 것이다)
<AdaBoosting 알고리즘 계산과정>
모델 정의 - 몇 개의 모델을 쓸 것인가 -> M개
첫번째 Dataset에 example i가 선택될 확률 --- > 모든 데이터에게 동등한 선택확률 부여
1. 모델 마다 가중치 초기화
이제 각각의 앙상블 개별 모델 (1/M)에게 다음과 같은 반복문 실행
2. Stumptree (굉장히 weak한 모델)을 사용해서 Dm(m번째 데이터셋)을 활용해서 학습 - (a)
3. 그리고 오분류를 계산 - (b) 즉, 예측중에서 잘못 분류한 갯수 / 전체 데이터 수
4. 알파 am을 계산
ex) err =0.5 => log((1-0.5)/0.5) = log1 = 0
(0.5에 가까우면 0에 가까워짐 (신뢰할 수 없기 때문에 이 모델의 a를 0에 가깝게 만든다)
알파값이 커질 수록 신뢰할 만한 모델
5. 가중치 업데이트 (에이다 부스팅 알고리즘을 활용하여)
Dm(i) exp(-알파t * Yt * ht(xi)) => 못맞추는 데이터의 가중치 증폭 (핵심!!) (데이터의 가중치를 업데이트)
못맞추고 있다면 = Dm 에서 i가 선택할 확률이 증가 (Yi * Hm(Xi)가 -1 => -a와 곱하면 +값 )
잘맞추고 있다면 = Dm 에서 i가 선택될 확률 감소 (Yi * Hm(Xi)가 +1 => -a와 곱하면 -값)
5-1. 업데이트된 가중치를 활용해서 가중치를 정규화 해주어야 한다
즉, 업데이트된 가중치 / 업데이트된 가중치 합을 통해서 정규화
결국 이를 통해서 모델 마다 특정 데이터에 강한 모델들이 만들어 진다
(즉, 이 데이터에는 이 모델, 저 데이터에는 저 모델이 만들어 지는 것이다)
6. 결국 지정해 놓은 모델 수에 도달 하거나 완벽한 모델이 만들어진다면 학습이 중단되고
이를 통해서 각 모델 마달 예측과 각 모델의 가중치를 곱해서 가장 높은 확률의 클래스를 예측클래스로 만든다
코드로 직접 구현한 AdaBoost 모델 :
from sklearn import tree
import pandas as pd
import numpy as np
import math
from sklearn.datasets import load_breast_cancer
from sklearn.metrics import confusion_matrix
data = load_breast_cancer()
X_train = data.data
y_train = np.where(data.target == 0, 1, -1)
def AdaBoost(X_train, y_train, n_estimators):
#분류기를 닮을 리스트 생성
classifiers = []
#가중치 초기화(데이터 수만큼 가중치 생성)
N = len(y_train)
w_i = np.array([1 / N] * N)
#T = 사용한 기본 모델 갯수
T = n_estimators
#각 모델의 에러를 저장할 리스트
clf_erros = []
#각 모델 마다 학습
for t in range(T):
clf = tree.DecisionTreeClassifier(max_depth = 1) #깊이가 1인 의사결정나무 - 매우 weak한 모델
clf.fit(X_train, y_train, sample_weight = w_i)
#y_hat (각모델의 예측 y값)
y_pred = clf.predict(X_train)
#(b)식 알고리즘 - 전체 가중치 합중에 예측을 잘못한 가중치의 비율
## np.where(y_train != y_pred, w_i, 0) -> 예측값과 실제값이 같지 않다면 해당 위치값을 가중치로, 같다면 0으로 지정
error = np.sum(np.where(y_train != y_pred, w_i, 0)) / np.sum(w_i)
#(c)식 알고리즘 - ex) err =0.5 => log((1-0.5)/0.5) = log1 = 0
###(0.5에 가까우면 0에 가까워짐 (신뢰할 수 없기 때문에 이 모델의 a를 0에 가깝게 만든다)
alpha = np.log((1-error) / error)
#분류기 저장소에 알파와 모델을 저장한다
classifiers.append((alpha, clf))
#가중치 업데이트 (d)식 [핵심 알고리즘] - 못맞춘 데이터일 수록 가중치 증가
w_i = np.where(y_train != y_pred, w_i*np.exp(alpha), w_i)
w_i = w_i / sum(w_i)
return classifiers # 학습된 모델 알파와 모델 return
#Line 3 함수
def predict(clfs, x):
s = np.zeros(len(x))
for (alpha, clf) in clfs:
s += alpha * clf.predict(x)
return np.sign(s)
'ML 🐼 > 머신러닝 💕' 카테고리의 다른 글
[Deep한 머신러닝] Boosting 부스팅 3편 (GradientBoost Classification) (0) | 2022.12.13 |
---|---|
[Deep한 머신러닝] Boosting 부스팅 2편(GradientBoosting Regression) (0) | 2022.12.12 |
[핸즈온머신러닝] 앙상블(Ensemble) 학습 (2) [부스팅 ~ 스태킹] (0) | 2022.11.30 |
[핸즈온머신러닝] 앙상블(Ensemble) 학습 (1) [보팅 ~ 랜덤 포레스트] (0) | 2022.11.29 |