Machine Learning/Basic

[5-3-(2)] 트리의 앙상블 - 엑스트라 트리, 그레이디언트 부스팅, 히스토그램 기반 그레이디언트 부스팅

jwjwvison 2021. 4. 10. 23:48

이 포스팅은 혼자 공부하는 머신러닝 + 딥러닝 책을 공부하고 정리한것 입니다.


 엑스트라 트리(Extra Tree)는 랜덤 포레스트와 매우 비슷하게 동작한다. 기본적으로 100개의 결정 트리를 훈련한다. 랜덤 포레스트와 동일하게 결정 트리가 제공하는 대부분의 매개변수를 지원한다. 또한 전체 특성 중에 일부 특성을 랜덤하게 선택하여 노드를 분할하는 데 사용한다.

 

 랜덤 포레스트와 엑스트라 트리의 차이점은 부트스트랩 샘플을 사용하지 않는다는 점이다. 즉 각 결정 트리를 만들 때 전체 훈련 세트를 사용한다. 대신 노드를 분할할 때 가장 좋은 분할을 찾는 것이 아니라 무작위로 분할한다.

 하나의 결정 트리에서 특성을 무작위로 분할한다면 성능이 낮아지겠지만 많은 트리를 앙상블 하기 때문에 과대적합을 막고 검증 세트의 점수를 높이는 효과가 있다.

 

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_score']),np.mean(scores['test_score']))

 랜덤 포레스트와 비슷한 결과를 얻었다. 이 예제는 특성이 많지 않아 두 모델의 차이가 크지 않다. 보통 엑스트라 트리가 무작위성이 좀 더 크기 때문에 랜덤 포레스트보다 더 많은 결정 트리를 훈련해야 한다. 하지만 랜덤하게 노드를 분할하기 때문에 빠른 계산 속도가 엑스트라 트리의 장점이다.

 

 결정 트리는 최적의 분할을 찾는 데 시간을 많이 소모한다. 특히 고려해야 할 특성의 개수가 많을 때는 더 그렇다. 만약 무작위로 나눈다면 훨씬 빨리 트리를 구성할 수 있다.

 

et.fit(train_input,train_target)
print(et.feature_importances_)

  지금까지 비슷하지만 조금 다른 2개의 앙상블 학습을 알아보았다. 다음은 이 둘과 다른 방식을 사용하는 앙상블 학습이다.

 

 

그레이디언트 부스팅

그레이디언트 부스팅(gradient boosting)은 깊이가 얕은 결정 트리를 사용하여 이진 트리의 오차를 보완하는 방식으로 앙상블 하는 방법이다. 사이킷런의 GradientBoostingClassifier는 기본적으로 깊이가 3인 결정 트리를 100개 사용한다. 깊이가 얕은 결정 트리를 사용하기 때문에 과대적합에 강하고 일반적으로 높은 일반화 성능을 기대할 수 있다.

 

 경사 하강법을 사용하여 트리를 앙상블에 추가한다. 분류에서는 로지스틱 손실 함수를 사용하고 회귀에서는 평균 제곱 오차 함수를 사용한다. 경사 하강법이 손실 함수의 낮은 곳으로 천천히 조금씩 이동해야 한다는것 처럼 그레이디언트 부스팅도 마찬가지이다. 그래서 깊이가 얕은 트리를 사용하는 것이다. 또 학습률 매개변수로 속도를 조절한다.

 

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_score']))

 거의 과대적합이 되지 않았다. 그레이디언트 부스팅은 결정 트리의 개수를 늘려도 과대적합에 매우 강하다. 학습률을 증가시키고 트리의 개수를 늘리면 조금 더 성능이 향상될 수 있다.

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_score']))

 결정 트리 개수를 500개로 5배나 늘렸지만 과대적합을 잘 억제하고 있다. 학습률 learning_rate의 기본값은 0.1이다.

 

gb.fit(train_input,train_target)
print(gb.feature_importances_)

 재미있는 매개변수, 트리 훈련에 사용할 훈련 세트의 비율을 정하는 subsample이 있다. 이 매개변수의 기본값은 1.0으로 전체 훈련 세트를 사용한다. 하지만 1보다 작으면 훈련 세트의 일부를 사용한다. 이는 마치 경사 하강법 단계마다 일부 샘플을 랜덤하게 선택하여 진행하는 확률적 경사 하강법이나 미니배치 경사 하강법과 비슷하다.

 

 일반적으로 그레이디언트 부스팅이 랜덤 포레스트보다 조그 더 높은 성능을 얻을 수 있다. 하지만 순서대로 트리를 추가하기 때문에 훈련 속도가 느리다. 즉 GradientBoostingClassifier에는 n_jobs 매개변수가 없다.

 

 그레이디언트 부스팅의 속도와 성능을 더욱 개선한 것이 히스토그램 기반 그레이디언트 부스팅이다.

 

 

히스토그램 기반 그레이디언트 부스팅

히스토그램 기반 그레이디언트 부스팅(Histogram-based Gradient Boosting)은 정형 데이터를 다루는 머신러닝 알고리즘 중에 가장 인기가 높은 알고리즘이다. 히스토그램 기반 그레이디언트 부스팅은 먼저 입력 특성을 256개의 구간으로 나눈다. 따라서 노드를 분할할 때 최적의 분할을 매우 빠르게 찾을 수 있다. 

 히스토그램 기반 그레이디언트 부스팅은 256개의 구간 중에서 하느를 뗴어 놓고 누락된 값을 위해서 사용한다. 따라서 입력에 누락된 특성이 있더라도 이를 따로 전처리할 필요가 없다. 

 일반적으로 HistGradientBoostingClassifier는 기본 매개변수에서 안정적인 성능을 얻을 수 있다.

 

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']))

 과대적합을 잘 억제하면서 그레이디언트 부스팅보다 조금 더 높은 성능을 제공한다.

 히스토그램 기반 그레이디언트 부스팅이 다양한 특성을 골고루 잘 평가한다고 예상할 수 있다.

 

 

hgb.score(test_input,test_target)

 앙상블 모델은 확실히 단일 결정 트리보다 좋은 결과를 얻을 수 있다. 사이킷런 말고도 히스토그램 기반 그레이디언트 부스팅 알고리즘을 구현한 라이브러리가 여럿 있다.

 

 가장 대표적인 라이브러리는 XGBoost 이다. 사이킷런의 cross_validate() 함수와 함께 사용할 수도 있다. XGBoost는 다양한 부스팅 알고리즘을 지원한다. tree_method 매개변수를 'hist'로 지정하면 히스토그램 기반 그레이디언트 부스팅을 사용할 수 있다.

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']))

 

 널리 사용하는 또 다른 히스토그램 기반 그레이디언트 부스팅 라이브러리는 LightGBM이다. 이는 빠르고 최신 기술을 많이 적용하고 있어 인기가 점점 높아지고 있다.

from lightgbm import LGBMClassifier

lgb=LGBMClassifier(random_state=42)
scores=cross_validate(lgb,train_input,train_target,return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']),np.mean(scores['test_score']))

 

 

결론


'Machine Learning > Basic' 카테고리의 다른 글

[6-2] k-평균  (0) 2021.04.13
[6-1] 군집 알고리즘  (0) 2021.04.13
[5-3-(1)] 트리의 앙상블 - 랜덤 포레스트  (0) 2021.04.10
[5-2] 교차 검증과 그리드 서치  (0) 2021.04.07
[5-1] 결정 트리  (0) 2021.04.07