on
[모델 알고리즘] 앙상블 - 그레이디언트 부스팅
[모델 알고리즘] 앙상블 - 그레이디언트 부스팅
≪ '앙상블 학습' 목차 ≫
▶ 배깅, 페이스팅
▶ 랜덤포레스트
▶ 에이다부스팅
▶ 그레이디언트부스팅
1. 그레이디언트 부스팅
2. 그레이디언트 부스팅 모델 구현
3. 최적 트리 수
4. 확률적 그레이디언트 부스팅
▶ 스태킹
1. 그레이디언트 부스팅
인기 많은 또 하나의 부스팅 알고리즘은 그레이디언트 부스팅이다.
그레이디언트 부스팅은 앙상블에 이전까지의 오차를 보정하도록 예측기를 순차적으로 추가한다.
에이다부스터처럼 반복마다 샘플의 가중치를 수정하는 대신, 이전 예측이 만든 잔여 오차에 새로운 예측기를 학습시킨다.
from sklearn.tree import DecisionTreeRegressor tree_reg1 = DecisionTreeRegressor(max_depth=2) tree_reg1.fit(X,y) y2 = y - tree_reg1.predict(X) tree_reg2 = DecsionTreeRegressor(max_depth=2) tree_reg2.fit(X,y2) y3 = y2 - tree_reg2.predict(X) tree_reg3 = DecisionTreeRegressor(max_depth=2) tree_reg3.fit(X,y3) #새로운 샘플에 대한 예측을 만들려면 모든 트리의 예측을 더하면 된다. y_pred = sum(tree_reg.predict(X_new) in (tree_reg1, tree_reg2, tree_reg3)
2. 그레이디언트 부스팅 모델 구현
사이킷런에서 GradientBoostingRegressor를 통해 그레이디언트 부스티드 회귀 트리를구현할 수 있고, GradientBoostingClassifier를 통해 그레이디언트 부스티드 분류 트리를 구현할 수 있다.
GradientBoostingRegressor 의 기본 손실 함수는 최소 제곱법(ls) 이고, GradientBoostingClassifier 의 기본 손실 함수는 로지스틱 손실 함수(deviance) 이다. 매개 변수 loss 를 통해, 다른 손실 함수로 설정할 수 있다.
ex. exponential, huber, lad,(최소 절댓값 오차), quantile(사분위수 손실 함수)
결정 트리를 기반 예측기로 사용하는 간단한 회귀 문제를 풀어보자.
이를 그레이디언트 트리 부스팅 또는 그레이디언트 부스티드 회귀 트리(GBRT) 라고 한다.
사이킷런에서 GradientBoostingRegressor를 사용하면 GBRT 앙상블을 간단하게 훈련시킬 수 있다.
from sklearn.ensembles import GradientBoostingRegressor gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=3, learning_rate=1.0) gbrt.fit(X,y)
GradientBoostingRegressor의 매개 변수 중 learning_rate 는 각 트리의 기여 정도를 조절한다.
낮게 설정하면 앙상블을 훈련 세트에 학습시키기 위해 많은 트리가 필요하지만 예측 성능은 좋다.
이는 축소라고 불리는 규제 방법이다.
왼쪽은 훈련 세트를 학습하기에 트리가 충분하지 않은 반면, 오른쪽은 트리가 너무 많아 훈련 세트에 과대 적합되었다.
3. 최적 트리수
그레이디언트 부스팅 모델을 구성하는 최적의 트리수는 어떻게 찾을까?
■ 방법1
많은 수의 트리를 훈련시키고 각 훈련 단계에서 검증 오차를 측정하여, 검증 오차가 최소인 예측기까지 앙상블 구성한다.
import numpy as np from sklearn.model_selection import train_test_split from sklearn.metrics import mean_squared_error X_train, X_val, y_train, y_val = train_test_split(X, y) gbrt = GradientBoostingRegressor(max_depth=2, n_estimators=120) gbrt.fit(X_train, y_train) #staged_predict() 함수를 사용해, 각 훈련 단계에서 만들어진 예측기를 순회하는 반복자를 반환한다. #각 훈련 단계에서 예측기 마다 검증 오차 계산한다. errors = [mean_squared_errors(y_val, y_pred) for y_pred in gbrt.staged_predict(X_val)] #검증 오차가 가장 낮은 예측기까지 포함하는 앙상블을 구성한다. best_n_estimators = np.argmin(errors) + 1 #최적의 트리수로 다시 훈련시킨다. gbrt_best = GradientBoostingRegressor(max_depth=2, n_estimators=best_n_estimators) grrt_best.fit(X_train, y_train)
■ 방법2
실제로 훈련을 중지하는 방법으로 조기 종료를 구현할 수 있다.
사이킷런에서 GradientBoostingRegressor 의 매개 변수 warm_start = True 로 설정하면, fit() 메서드가 호출될 때 기존 트리를 유지한 상태에서 예측기 훈련을 추가할 수 있다.
gbrt = GradientBoostingRegressor(max_depth=2, warm_start=True) min_val_error = float('inf') error_going_up = 0 for n_estimators in range(120) : gbrt.n_estimators = n_estimators gbrt.fit(X_train, y_train) y_pred = gbrt.predict(X_val) val_error = mean_squared_error(y_val, y_pred) if val_error < min_val_error : min_val_error = val_error error_going_up = 0 else : error_going_up += 1 #min_val_error 가 5번 이상 갱신되지 않으면 조기 종료 실행 if error_going_up == 5 : break
4. 확률적 그레이디언트 부스팅
GradientBoostingRegressor는 매개 변수 subsamples 를 통해, 각 트리가 훈련할 때 사용할 훈련 샘플의 비율을 지정할 수 있다.
랜덤 포레스트처럼, 데이터와 특성을 샘플링하는 식으로 그레이디언트 부스팅에 랜덤한 요소를 추가하였다.
예를 들어, subsampels=0.25로 설정하면 각 트리는 무작위로 선택된 25%의 훈련 샘플로 훈련하게 된다.
이는 편향이 높아지는 대신 분산이 낮아지며 훈련 속도가 매우 빨라진다.
이런 기법을 확률적 그레이디언트 부스팅이라고 한다.
■ XGBoost
최적화된 그레이디언트 부스팅 구현으로 XGBoost 파이썬 라이브러리가 유명하다.
XGBoost는 병렬처리 가능하도록 변형하여 속도가 빠르다. 또한 과적합의 위험을 줄이기 위한 규제항을 추가하여 성능도 좋다.
import xgboost xgb_reg = xgboost.XGBRegressor() xgb_reg.fit(X_train, y_train) y_pred = xgb_reg.predict(X_val)
XGBoost 는 자동 조기 종료와 같은 여러 좋은 기능도 제공한다.
xgb_reg = xgboost.XGBRegressor() xgb_reg.fit(X_train, y_train, eval_set=[X_val, y_val], early_stopping_rounds=2) y_pred = xgb_reg.predict(X_val)
■ ligthGBM
lightGBM은 기존 트리 기반 알고리즘 '균형 트리 분할' 과 다르게, '리프 중심 트리 분할' 방식이다.
즉 lightGBM은 트리의 균형을 맞추지 않고, 최대 손실값을 가지는 리프 노드를 계속 분할하면서 트리의 깊이가 깊어지고 비대칭적인 트리를 생성한다. 이로써 속도가 빨라지는 효과가 있다.
사이킷런에서 LGBMRegressor 의 매개 변수 bagging_fraction, feature_fraction 등을 통해 샘플과 특성의 랜덤 선택 비율을 설정할 수 있다.
from lightgbm import LGBMRegressor lgb_reg = LGBMRegressor(random_state=42) lgb_reg.fit(X_train, y_train) y_pred = lgb_red(X_val)
from http://lets-start-data.tistory.com/51 by ccl(A) rewrite - 2021-08-13 15:00:14