Notice
Recent Posts
Recent Comments
Link
«   2026/01   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Archives
Today
Total
관리 메뉴

공부일기

ML/ 앙상블 학습, 랜덤 포레스트, 엑스트라 트리, 그라디언트 부스팅 본문

ML

ML/ 앙상블 학습, 랜덤 포레스트, 엑스트라 트리, 그라디언트 부스팅

석새우 2026. 1. 20. 15:32

정형 데이터를 다루는 데 가장 뛰어난 성과를 내는 알고리즘인 앙상블 학습 들에 대해서 알아보겠슈.

 

랜덤 포레스트

대표적인 결정 트리 기반의 앙상블 학습 방법이다. 부트 스트랩 샘플을 사용하고 일부 특성을 선택하여 트리를 만든다.

 

부트 스트랩 샘플이란 예를 들어 1000개의 샘플이 있다면 1000개의 샘플을 중복해서 뽑는 것이다.

 

RandomForestClassifier는 기본적으로 전체 특성 개수의 제곱근만큼의 특성을 선택한다. Regressor는 전체 특성을 사용한다.

 

기본적으로 100개의 결정 트리를 훈련하고, 분류 모델은 각 트리의 클래스별 확률을 평균하고 그중에서 더 높은 확률을 가진 클래스를 예측으로 삼고 회귀일때는 각 트리의 예측을 평균한다.

 

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

 

살짝 과대 적합된 모델이 완성됐다.

 

특성 요도를 살펴본다.

 

rf.fit(train_input, train_target)
print(rf.feature_importances_)
[0.23167441 0.50039841 0.26792718]

 

앞에서 했었던 결정 트리에 비해서 두번째 특성인 당도가 조금 감소하고 도수와 pH가 상승한 걸 볼 수 있다. 이를 통해 일반화 성능을 높일 수 있다.

 

RandomForestClassifier에서는 훈련 세트에서 중복을 허용(부트 스트랩)하여 훈련한다고 했는데, 이때 샘플에 포함되지 않고 남는 샘플이 생길 수 있다. 이런 샘플들을 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_)
0.8934000384837406

 

이런 식으로 oob_score 을 True로 바꿔주면 쉽게 추가 검증 점수를 확인할 수 있다.

 

엑스트라 트리

엑스트라 트리는 랜덤 포레스트와 비슷한데 부트스트랩 샘플을 사용하지 않는다. 전체 훈련 세트를 사용해서 각각의 결정 트리를 만들고 무작위로 노드를 분할한다.

 

쉽게 말하면 "아 모르겠다 걍 대충해~~~" 하는 앙상블이다.

 

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

 

중요도 결과를 보면 결정 트리보다 당도에 대한 의존성이 작다.

 

et.fit(train_input, train_target)
print(et.feature_importances_)
[0.20183568 0.52242907 0.27573525]

 

 

그라디언트 부스팅

그라디언트 부스팅은 이름에서도 알 수 있듯이 경사 하강법을 사용한다. 쉽게 말하면 이전에 훈련 시킨 모델이 틀린 부분을 다음 모델이 보완하는 작업을 쭉 거친다.

 

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

 

그라디언트 부스팅은 결정 트리의 개수를 늘려도 과대적합에 매우 강하다.

 

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

 

n_estimators가 결정 트리 개수이고 learning_rate이 이제 전에꺼를 어느정도의 강도로 수정을 할 거냐 이거다.

그라디언트 부스팅이 랜덤 포레스트보다 조금 더 높은 성능을 얻지만 순서대로 트리를 추가하기 때문에 훈련 속도가 느리다.

 

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

정형 데이터를 다루는 머신러닝 알고리즘 중에서 가장 인기가 높은 알고리즘이다.

값을 한개한개 다 보는게 아니라 특성을 256개의 구간으로 나눠서 분할한다.

 

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.9321723946453317 0.8801241948619236

 

좋은 점수군,,,

 

히스토그램 기반 그라디언트 부스팅은 특성중요도를 계산하기 위해 permutation_importance() 라는 함수를 사용한다. 이 함수는 특성을 하나씩 랜덤하게 섞어서 모델의 성능이 변화하는지를 관찰하여 어떤 특성이 중요한지를 계산한다.

 

from sklearn.inspection import permutation_importance

hgb.fit(train_input, train_target)
result = permutation_importance(hgb, train_input, train_target, n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)
[0.08876275 0.23438522 0.08027708]

 

n_repeats가 특성을 몇번 섞을 지 결정하는 변수이다.

result는 특성 중요도(importances), 평균(importances_mean), 표준 편차(importances_std)를 가지고 있다.

 

print(hgb.score(train_input, train_target))
print(hgb.score(test_input, test_target))
0.924956705791803
0.8723076923076923

 

좋은 점수가 나온다.

 

사이킷런 말고도 그라디언트 부스팅 알고르지므을 구현한 라이브러리가 있다.

 

XGBoost

from xgboost import XGBClassifier
xgb = XGBClassifier(tree_method='hist', random_state=42)
scores = cross_validate(xgb, train_input, train_target, return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
0.9567059184812372 0.8783915747390243

 

tree_method를 hist로 지정하면 히스토그램 기반 그라디언트 부스팅을 사용할 수 있따.

 

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

 

LightGBM은 마이크로소프트에서 만들었는데 인기가 점점 높아진다고 한다..

 

이상...