04-05. GBM(Gradient Boosting Machine)

Park Jong Hun·2021년 2월 19일
1

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.


1. GBM의 개요 및 실습


부스팅 알고리즘은 여러 개의 약한 학습기(weak learner)를 순차적으로 학습/예측하며 잘못 예측한 데이터에 가중치 부여를 통해 오류를 개선해 나가면서 학습하는 방식이다. 부스팅의 대표적인 구현은 AdaBoost(Adaptive boosting)과 그래디언트 부스트(Gradient Boost)가 있다. 에이다 부스트(AdaBoost)는 오류 데이터에 가중치를 부여하면서 부스팅을 수행하는 대표적인 알고리즘이다.
위 이미지처럼 "+"와 "-"로 구성된 피쳐 dataset이 있다면 weak learner 분류기 1이 step 1에서 분류를 하고 step 2에선 잘못 분류한 data에 가중치를 부여한다. 이 과정을 step 5까지 반복하면 총 3개의 weak learner 분류기를 통해 분류를 하게 되고 1개의 weak learner 분류기를 사용할 때보다 정확도가 높아진 것을 알 수 있다.

GBM(Gradient Boosting Machine)도 AdaBoost와 비슷하지만 가중치 업데이트를 경사하강법(Gradient Descent)을 이용하는 것이 가장 큰 차이이다. 오류값은 (실제값-예측값)이 되고 이 오류 식을 최소화하는 방향으로 반복적으로 가중치를 업데이트한다. 그리고 GBM은 CART 기반의 다른 알고리즘과 마찬가지로 분류 뿐만 아니라 회귀도 가능하다. 사이킷런은 GBM 기반의 분류를 위해 GradientBoostinClassifier 클래스를 제공한다. 사이킷런의 GBM을 이용해 사용자 행동 dataset을 예측 분류해 보고, 학습 시간도 같이 확인해 보겠다.

from sklearn.ensemble import GradientBoostingClassifier
import time
import warnings
warnings.filterwarnings('ignore')

X_train, X_test, y_train, y_test = get_human_dataset()

# GBM 수행 시간 측정을 위함. 시작 시간 설정.
start_time = time.time()

gb_clf = GradientBoostingClassifier(random_state=0)
gb_clf.fit(X_train , y_train)
gb_pred = gb_clf.predict(X_test)
gb_accuracy = accuracy_score(y_test, gb_pred)

print('GBM 정확도: {0:.4f}'.format(gb_accuracy))
print("GBM 수행 시간: {0:.1f} 초 ".format(time.time() - start_time))

[output] default 파라미터만으로 93.86%의 정확도를 보이는 것을 알 수 있다. 일반적으로 GBM이 랜덤 포레스트보다 예측 성능이 뛰어난 경우가 많다. 하지만 수행 시간이 오래 걸리고 hyper parameter 튜닝도 더 많은 시간이 필요로 하게 된다. 이 수행 시간 문제는 GBM이 극복해야 할 중요한 과제이다.


2. GBM 하이퍼 파라미터 및 튜닝


트리 기반 자체의 파라미터도 있지만 생략하고 나머지 다른 파라미터에 대해 설명하겠다.

  • loss : 경사 하강법에서 사용할 비용 함수를 지정한다. defalut는 'deviance'이다.
  • learning_rate : GBM이 학습을 진행할 때마다 적용하는 학습률이다. Weak learner가 순차적으로 오류 값을 보정해 나가는데 적용하는 계수이다. 0 ~ 1의 값으로 지정 가능하며 defalut는 0.1이다. 너무 작은 값을 적용하면 업데이트 되는 값이 작아져서 최소 오류 값을 찾아 예측 성능이 높아질 가능성이 높지만 많은 weak learner는 순차적인 반복이 필요해서 수행 시간이 오래 걸리고, 모든 weak learner의 반복이 완료되어도 최소 오류 값을 찾지 못할 수 있다. 반대로 큰 값을 적용하면 최소 오류 값을 찾지 못하고 그냥 지나쳐 버려 예측 성능이 떨어질 가능성이 있지만 빠른 수행이 가능하다. 이러한 특성때문에 learning_rate는 n_estimators와 상호 보완적으로 조합해 사용하는데 작은 learning_rate를 사용하고 n_estimator를 크게 하면 최고의 성능을 보일 수 있는 지점까지 학습이 가능하겠지만 수행 시간이 너무 오래 걸리고 예측 성능도 들이는 시간 만큼 현격하게 좋아지지는 않는다.
  • n_estimators : weak learner의 개수이다. weak learner가 순차적으로 오류를 보정하므로 개수가 많을수록 예측 성능이 일정 수준까지는 좋아질 수 있다. 하지만 개수가 많을수록 수행 시간이 오래 걸린다. default 값은 100이다.
  • subsample : weak learner가 학습에 사용하는 데이터의 샘플링 비율이다. default 값은 1이며, 전체 학습 데이터를 기반으로 학습한다는 의미이다. 만약 0.5 이면 학습 데이터의 50%를 의미한다. 과적합이 염려되는 경우 subsample을 1보다 작은 값으로 설정한다.

GridSearchCV를 이용하여 hyper parameter를 최적화해 보겠다.

from sklearn.model_selection import GridSearchCV

params = {
    'n_estimators':[100, 500],
    'learning_rate' : [ 0.05, 0.1]
}
grid_cv = GridSearchCV(gb_clf , param_grid=params , cv=2 ,verbose=1)
grid_cv.fit(X_train , y_train)
print('최적 하이퍼 파라미터:\n', grid_cv.best_params_)
print('최고 예측 정확도: {0:.4f}'.format(grid_cv.best_score_))

[output] 교차 검증 세트에서 90.13%의 정확도가 나왔고 해당 hyper parameter 설정으로 테스트 dataset에도 적용하여 예측 정확도를 확인해 보겠다.

# GridSearchCV를 이용하여 최적으로 학습된 estimator로 predict 수행. 
gb_pred = grid_cv.best_estimator_.predict(X_test)
gb_accuracy = accuracy_score(y_test, gb_pred)
print('GBM 정확도: {0:.4f}'.format(gb_accuracy))

[output] GBM은 과적합에도 강한 뛰어난 예측 성능을 가진 알고리즘이지만 수행 시간이 오래 걸린다는 단점이 있다. 이 알고리즘이 처음 소개되고 GBM을 기반으로한 많은 알고리즘이 나왔으며 가장 각광 받고 있는 2개의 Gradient Boosting 기반의 ML 패키지는 XGBoost와 LightGBM이다.

profile
NLP, AI, LLM, MLops

0개의 댓글