[머신러닝] 트리의 앙상블 알고리즘 - 랜덤 포레스트, 엑스트라 트리, 부스팅

hyun·2022년 8월 24일

머신러닝

목록 보기
9/10
post-thumbnail

📚 앙상블(ensemble) 알고리즘

  • 여러 개의 분류기를 학습하고 그 결과를 합쳐서 최선의 예측 결과를 낸다.
  • 성공률이 단일 분류기보다 높다 (낮으면 높은 것을 목표로 한다)

🌲 랜덤 포레스트 알고리즘

  • 주어진 표본을 재표본추출하여 같은 크기인 다양한 변동성의 표본을 만든다.(부트스트래핑)
  • 각 노드를 분할할 때, 무작위 개수의 특성을 선택한다
    (sklearn의 RandomForestClassifier는 기본적으로 전체특성\sqrt{전체\,특성}개를 선택한다. RandomForestRegressor 회귀는 전체 특성.)
  • 많은 트리를 이렇게 학습한다.
  • 각 트리의 클래스별 확률을 평균하여 가장 높은 확률의 클래스를 예측.

🎄 엑스트라 트리 알고리즘

  • 부트스트래핑을 사용하지 않는다.
  • 노드를 나눌 때, 무작위로 나눈다. (계산을 하지 않는다) 따라서 빠르다.
  • 무작위성이 커 많은 모델을 훈련해야 한다.
  • 랜덤이기에 과대적합을 막고, 검증 세트의 점수를 높일 수 있다.

🎄 그래디언트 부스팅 알고리즘

  • 깊이가 얕은 트리를 이용해서 이전 트리의 오차를 보완.
  • 경사하강법을 이용해서 트리를 추가
  • 분류에서는 로지스틱 손실함수, 회귀에서는 평균제곱 오차 함수를 이용
  • 깊이가 얕은 트리를 계속 추가하면서 경사하강법
  • 오래 걸린다 ㅠㅠ

🌴 히스토그램 기반 그래디언트 부스팅

  • 그래디언트의 단점을 보완
  • 입력 특성을 256개로 나눠 최적 분할을 빠르게 찾을 수 있음
  • 256개 구간에서 하나를 떼어놓고 누락된 값을 위해 사용 -> 전처리 필요 없음!

💻 실습

랜덤 포레스트

사이킷런의 RandomForestClassifier 클래스를 이용한다.

from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
rf = RandomForestClassifier(n_jobs=-1, random_state=42)

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

각 특성 중요도는 feature_importances에 있다.

# 랜덤 포레스트의 특성 중요도는 각 결정트리의 값을 취합
rf.fit(train_input, train_target)
print(rf.feature_importances_)
# 알코올 당도 pH
# 랜덤 포레스트는 특성을 랜덤으로 선택하기 때문에 하나의 특성에 과도하게 집중하지 않음 -> 과대적합을 줄이고 일반화 성능 개선

랜덤 포레스트에서 Bootstrap 샘플에 포함되지 않은 것을 OOB (Out Of Bag)샘플이라 하는데, 이를 통한 검증을 할 수 있다.

rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score_)

엑스트라 트리

사이킷런의 ExtraTreesClassifier를 이용한다.

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

역시 feature_importance를 통해 특성 중요도를 알 수 있다.

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

그래디언트 부스팅

사이킷런의 GradientBoostingClassifier를 이용한다.

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

학습률 α\alpha는 learning_rate 파라미터를 통해 정할 수 있다.

# 학습률과 트리 증가 (학습률 디폴트 0.1)
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']))

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

성능이 짱이라고 한다.
아직 사이킷런에서는 테스트 단계라 enable_hist_gradient_boosting 도 import해야 한다.
sklearn의 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']))


앙상블 모델은 단일 모델보다 성능이 좋다. 당연히 더 많은 트리를 돌리니까 !

0개의 댓글