kang's study
11일차 : 트리의 앙상블 본문
트리의 앙상블 (tree ensemble)¶
정형 데이터에서 가장 뛰어난 성능을 내는 머신러닝 알고리즘 중 하나¶
랜덤포레스트 (RandomForest)
결정트리를 랜덤하게 만들어 숲을 이룬다.
사이킷런에 구현된 앙상블 학습 알고리즘으로 학습
In [1]:
import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
In [2]:
# 데이터 불러오기
wine = pd.read_csv('https://bit.ly/wine_csv_data')
# 특성변수와 타겟변수 구분
data = wine[['alcohol', 'sugar', 'pH']].to_numpy()
target = wine['class'].to_numpy()
# 데이터 분할 (예측, 평가)
train_input, test_input, train_target, test_target = \
train_test_split(data, target, test_size=0.2, random_state=42)
랜덤 포레스트 훈련방법
부트스트랩 샘플 :¶
훈련세트와 크기를 같게 만든다.
훈련데이터에서 중복 가능하게 하여 랜덤하게 샘플을 추출한다.
샘플의 대표성을 줄이는 과정
특성의 개수 :
RandomForestClassifier는 전체 특성 개수의 제곱근만큼의 특성을 선택
ex 4개의 특성이라면 노드마다 2개를 랜덤하게 선택하여 사용해 최선의 분할을 찾음
RandomForestRegressor는 전체 특성 개수를 사용한다.
In [3]:
from sklearn.model_selection import cross_validate
from sklearn.ensemble import RandomForestClassifier
In [4]:
# 교차검증
# 랜덤포레스트는 기본적으로 100개의 결정트리를 사용
rf = RandomForestClassifier(n_jobs=-1, random_state=42)
scores = cross_validate(rf, train_input, train_target, return_train_score=True,
n_jobs=-1)
# train_score 출력 가능
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
In [5]:
rf.fit(train_input, train_target) # 모델을 훈련
print(rf.feature_importances_)
OOB(out of bag)샘플 : 부트스트랩 샘플에 포함되지 않고 남겨진 샘플들¶
In [6]:
# 남는 샘플로 검증세트 역할을 해본다
rf = RandomForestClassifier(oob_score=True, n_jobs=-1, random_state=42)
rf.fit(train_input, train_target)
print(rf.oob_score_)
엑스트라트리
결정트리를 만들 때 전체 훈련세트를 사용한다.
노드분할은 무작위로 한다. 결정트리에서 splitter='random'
무작위성을 주입하여 트리의 성장을 억제하는 방법이 다르다.
각 특성을 랜덤하게 분할하여 가장 좋은 불순도를 나타내는 하나를 찾는다.
속도가 빠르나 성능은 랜덤보다 트리를 늘려야 좋은 성능을 낼 수 있다.¶
In [7]:
from sklearn.ensemble import ExtraTreesClassifier
# s가 있다 주의
In [8]:
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']))
In [9]:
et.fit(train_input, train_target)
print(et.feature_importances_)
고려해야 할 특성의 개수가 많을 때 엑스트라 트리의 장점이 나타난다.
랜덤하게 노드를 분할하기에 계산 속다가 빠르다
In [10]:
from sklearn.ensemble import GradientBoostingClassifier
In [11]:
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']))
In [12]:
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']))
In [13]:
gb.fit(train_input, train_target)
print(gb.feature_importances_)
사이킷런¶
In [14]:
# 사이킷런 1.0 버전 아래에서는 다음 라인의 주석을 해제하고 실행하세요.
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingClassifier
In [15]:
hgb = HistGradientBoostingClassifier(random_state=42)
scores = cross_validate(hgb, train_input, train_target,
return_train_score=True, n_jobs=-1)
print(np.mean(scores['train_score']), np.mean(scores['test_score']))
과대적합을 잘 억제하고 그레이디언트 부스팅보다 조금 더 높은 성능을 제공해준다.
In [17]:
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)
# n_repeats기본(랜덤하게 섞을 횟수)은 5
print(result.importances_mean)
In [12]:
result = permutation_importance(hgb, test_input, test_target,
n_repeats=10, random_state=42, n_jobs=-1)
print(result.importances_mean)
# 실전에 투입하면 어떨지 예상도 해줌
# 성능이 떨어진다는 의미 그만큼 중요한 특성이다.
In [18]:
hgb.score(test_input, test_target)
Out[18]:
In [21]:
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']))
In [22]:
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']))
출처 : 박해선, 『혼자공부하는머신러닝+딥러닝』, 한빛미디어(2021), p263-280
'[학습 공간] > [혼공머신러닝]' 카테고리의 다른 글
13일차 : k-평균 (0) | 2022.03.03 |
---|---|
12일차 : 군집 알고리즘 (0) | 2022.03.03 |
10일차 : 교차검증과 그리드 서치 (0) | 2022.03.03 |
9일차 : 결정트리 (Decision tree) (0) | 2022.03.03 |
8일차 : 확률적 경사 하강법 (Stochastic Gradient Descent) (0) | 2022.03.03 |
Comments