Data Analysis & ML/Machine Learning

[Machine Learning][머신러닝][앙상블][부스팅] GradientBoosting

YSY^ 2020. 9. 3. 16:26

Boosting

  • 부스팅(Boosting)이란 단순하고 약한 학습기(Weak Learner)들를 결합해서 보다 정확하고 강력한 학습기(Strong Learner)를 만드는 방식.
  • 정확도가 낮은 하나의 모델을 만들어 학습 시킨뒤, 그 모델의 예측 오류는 두 번째 모델이 보완한다. 이 두 모델을 합치면 처음보다는 정확한 모델이 만들어 진다. 합쳐진 모델의 예측 오류는 다음 모델에서 보완하여 계속 더하는 과정을 반복한다.
  • 약한 학습기들은 앞 학습기가 만든 오류를 줄이는 방향으로 학습한다.

 

GradientBoosting

  • 처음 모델은 y를 예측 두번째 부터는 앞 모델이 만든 오류를 예측하고 그것을 앞 모델에 업데이트하면 오류를 줄일 수 있다.
  • 그 오류를 update할 때 뺄까 더할까를 gradient descent 방법을 쓴다. 미분해서 나오는 값의 음수를 취해서 적용.
  • 학습률을 작게하면 update가 조금씩 크면 많이 하게 된다. 그래서 크게하면 학습데이터에 너무 맞아 과대적합 될 수 있다.
  • 개별 모델로 Decision Tree 를 사용한다.
  • depth가 깊지 않은 트리를 많이 연결해서 이전 트리의 오차를 보정해 나가는 방식으로 실행한다.
  • 오차를 보정할 때 경사하강법(Gradient descent)을 사용한다.
  • 얕은 트리를 많이 연결하여 각각의 트리가 데이터의 일부에 대해 예측을 잘 수행하도록 하고 그런 트리들이 모여 전체 성능을 높이는 것이 기본 아이디어.
  • 분류와 회귀 둘다 지원하는 모델 (GradientBoostingClassifier, GrandientBoostingRegressor)
  • 훈련시간이 많이 걸리고, 트리기반 모델의 특성상 희소한 고차원 데이터에서는 성능이 않좋은 단점이 있다.

주요 파라미터

  • Decision Tree 의 가지치기 관련 매개변수
    • 각각의 tree가 복잡한 모델이 되지 않도록 한다.
  • learning rate
    • 이전 tree의 오차를 얼마나 강하게 보정할 것인지 제어하는 값.
    • 값이 크면 보정을 강하게 하여 복잡한 모델을 만든다. 학습데이터의 정확도는 올라가지만 과대적합이 날 수있다.
    • 값을 작게 잡으면 보정을 약하게 하여 모델의 복잡도를 줄인다. 과대적합을 줄일 수 있지만 성능 자체가 낮아질 수있다.
    • 기본값 : 0.1
  • n_estimators
    • tree의 개수 지정. 많을 수록 복잡한 모델이 된다.
  • n_iter_no_change, validation_fraction
    • validation_fraction에 지정한 비율만큼 n_iter_no_change에 지정한 반복 횟수동안 검증점수가 좋아 지지 않으면 훈련을 조기 종료한다.
  • 보통 max_depth를 낮춰 개별 트리의 복잡도를 낮춘다. (5가 넘지 않게) 그리고 n_estimators를 가용시간, 메모리 한도에 맞춘뒤 적절한 learning_rate을 찾는다.

GradientBoosting 컨셉

학습데이터

  • 키 , 좋아하는 색 , 성별로 몸무게를 예측하는 모델을 생성
  • feature: Height(m), Favorite Color, Gender
  • target: Weight(kg)

모델예측

  • 첫 모델은 Target 을 예측한다
  • Residual( 잔차 ) = 실제 Weight - 예측한 Weight
  • 잔차는 오차와 같은 의미

  • 두 번째 트리모델부터는 잔차를 예측하는 모델을 Feature 로 잔차(Residual)를 예측하는 트리모델을 생성한다

  • 관측치를 트리 모델로 잔차 오차 를 예측 한다
  • 위 그림에서 첫 번째 관측치의 경우 잔차가 16.8 이 나온다 . 그럼 그것을 첫 번째 예측 값이었던 평균인 71.2 에 더하면 실제 값인 88 이 나온다

  • 예측한 잔차를 그대로 더하면 학습데이터의 값은 100% 예측하겠지만 새로운 데이터에는 맞지 않을 가능성이 높다 . 과대적합
  • 그래서 예측한 잔차 오차 에 학습율을 곱한 값을 예측 값에 더한다
  • 학습율 : Learning 하이퍼 파라미터로 오차가 있는 예측값을 보정하는 비율
  • 위의 예를 보면 처음 예측한 71.2 가 72.9 로 실제 값에 좀더 가까이 예측했다

  • 줄어든 잔차를 예측하는 트리모델을 만들어 예측한 결과에 학습율을 곱한뒤 이전 예측 결과에 더한다•
  • 예측값 + 학습율 * 잔차예측값 = 새데이터
  • 위의 작업을 반복하여 잔차를 줄여 나간다

GradientBoosting으로 위스콘시 데이터 분류

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split

cancer = load_breast_cancer()
X = cancer.data
y = cancer.target
X_train, X_test, y_train, y_test = train_test_split(X, y, stratify=y, random_state=1)

from sklearn.ensemble import GradientBoostingClassifier

gb_clf = GradientBoostingClassifier(learning_rate=0.01)
gb_clf.fit(X_train, y_train)
#==> GradientBoostingClassifier(ccp_alpha=0.0, criterion='friedman_mse', init=None,
                           learning_rate=0.01, loss='deviance', max_depth=3,
                           max_features=None, max_leaf_nodes=None,
                           min_impurity_decrease=0.0, min_impurity_split=None,
                           min_samples_leaf=1, min_samples_split=2,
                           min_weight_fraction_leaf=0.0, n_estimators=100,
                           n_iter_no_change=None, presort='deprecated',
                           random_state=None, subsample=1.0, tol=0.0001,
                           validation_fraction=0.1, verbose=0,
                           warm_start=False)

pred_train = gb_clf.predict(X_train)
pred_test = gb_clf.predict(X_test)
from sklearn.metrics import accuracy_score, f1_score, recall_score, precision_score

def print_metrics(y, pred_y, title=None):
    if title:
        print(title)
    print("정확도:", accuracy_score(y, pred_y))
    print('재현율(recall):', recall_score(y, pred_y))
    print('정밀도(precision):', precision_score(y, pred_y))
    print('f1 score:', f1_score(y, pred_y))

컬럼중요도 조회

import pandas as pd
f_i_s = pd.Series(gb_clf.feature_importances_, index=cancer.feature_names).sort_values(ascending=False)
f_i_s.sort_values().plot(kind='barh', figsize=(10,5))

GridSearchCV 이용해 최적의 하이퍼파라미터 찾기

from sklearn.model_selection import GridSearchCV

param = {
    'n_estimators':[100,200,300,400,500], #생성할 결정트리 개수
    'learning_rate':[0.001, 0.01, 0.05, 0.1, 0.2], 
    'max_depth':[1,2,3]
}
gb_clf = GradientBoostingClassifier()
gs = GridSearchCV(gb_clf,
                  param_grid = param,
                  cv=5,
                  n_jobs=-1)

728x90
반응형