
๋ถ์คํ ์๊ณ ๋ฆฌ์ฆ
์ฌ๋ฌ๊ฐ์ ์ฝํ ํ์ต๊ธฐ๋ฅผ ์์ฐจ์ ์ผ๋ก ํ์ต-์์ธกํ๋ฉด์ ์๋ชป ์์ธกํ ๋ฐ์ดํฐ์ ๊ฐ์ค์น ๋ถ์ฌ๋ฅผ ํตํด ์ค๋ฅ๋ฅผ ๊ฐ์ ํด ๋๊ฐ๋ฉด์ ํ์ตํ๋ ๋ฐฉ์
๐ ฐ AdaBoost(Adaptive boosting)
๐ ฑ Gradient Boost

์์ด๋ค๋ถ์คํธ์ ์ ์ฌํ๋ ๊ฐ์ค์น ์ ๋ฐ์ดํธ๋ฅผ ๊ฒฝ์ฌํ๊ฐ๋ฒ์ ์ด์ฉํ๋ ๊ฒ์ด ํฐ ์ฐจ์ด
๋ฐ๋ณต ์ํ์ ํตํด ์ค๋ฅ๋ฅผ ์ต์ํํ ์ ์๋๋ก ๊ฐ์ค์น์ ์ ๋ฐ์ดํธ ๊ฐ์ ๋์ถํ๋ ๊ธฐ๋ฒ
GBM์ด ๋๋ค ํฌ๋ ์คํธ๋ณด๋ค๋ ์์ธก ์ฑ๋ฅ์ด ๋ฐ์ด๋จ
GBM์ ์ค๋๊ฑธ๋ฆฌ๊ณ ํ์ดํผ ํ๋ผ๋ฏธํฐ ํ๋๋๋ ฅ๋ ๋ ํ์ํ๋ค๋ ๋จ์ ์์.
loss : ์์ค ์ ๋(ํ๊ฐ ์ฒ๋๋ก ์ฌ์ฉ๋จ)
learning_rate : GBM์ด ํ์ต์ ์งํํ ๋๋ง๋ค ์ ์ฉํ๋ ํ์ต๋ฅ
n_estimators : weak_learner์ ๊ฐ์
subsample: ์ฝํ ํ์ต๊ธฐ๊ฐ ํ์ต์ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ ์ํ๋ง ๋น์จ
ํธ๋ฆฌ ์์๋ธ ํ์ต์์ ๊ฐ์ฅ ๊ฐ๊ด๋ฐ๊ณ ์๋ ์๊ณ ๋ฆฌ์ฆ ์ค ํ๋
โ ๋ฐ์ด๋ ์์ธก ์ฑ๋ฅ
โ GBM ๋๋น ๋น ๋ฅธ ์ํ ์๊ฐ
โ ๊ณผ์ ํฉ ๊ท์
โ Tree pruning (๋๋ฌด ๊ฐ์ง์น๊ธฐ)
โ ์์ฒด ๋ด์ฅ๋ ๊ต์ฐจ ๊ฒ์ฆ
โ ๊ฒฐ์๊ฐ ์์ฒด ์ฒ๋ฆฌ
์ค... ๊ทธ๋ฅ ์ต๊ฐ์ธ๋ฐ???
โถ ์ด๊ธฐ ๋ ์์ ์ธ XGBoost ํ๋ ์์ํฌ ๊ธฐ๋ฐ์ XGBoost๋ฅผ ํ์ด์ฌ ๋ํผ XGBoost ๋ชจ๋, ์ฌ์ดํท๋ฐ๊ณผ ์ฐ๋๋๋ ๋ชจ๋์ XGBoost ๋ชจ๋
์ผ๋ฐ ํ๋ผ๋ฏธํฐ ๋ํดํธ ํ๋ผ๋ฏธํฐ ๊ฐ์ ๋ฐ๊พธ์ง ์๋ ๊ธฐ๋ณธ ํ๋ผ๋ฏธํฐ
๋ถ์คํฐ ํ๋ผ๋ฏธํฐ ํธ๋ฆฌ ์ต์ ํ ๋ถ์คํ
๊ณผ ๊ด๋ จ ํ๋ผ๋ฏธํฐ ๋ฑ์ ์ง์ (์ฌ์ ์กฐ์ ํ๋ผ๋ฏธํฐ)
ํ์ต ํ์คํฌ ํ๋ผ๋ฏธํฐ ํ์ต ์ํ์ ์ค์ ํ๋ ํ๋ผ๋ฏธํฐ (ํ์ต ํ๋ผ๋ฏธํฐ)
[์ฃผ์ ์ผ๋ฐ ํ๋ผ๋ฏธํฐ]
booster
silent
nthread
[์ฃผ์ ๋ถ์คํฐ ํ๋ผ๋ฏธํฐ]
eta[default=0.3, alias: learning_rate]
num_boost_rounds
min_child_weight[default=1]
gamma[default=0, alias: min_split_loss
max_depth[default=6]
sub_sample[default=1]
colsample_bytree[default=1]
lambda[default=1, alias: reg_lambda]
alpha[default=0, alias: reg_alpha]
scale_pos_weight[default=1]
[ํ์ต ํ์คํฌ ํ๋ผ๋ฏธํฐ]
objective
bianry:logistic
multi:softmax
multi:softprob
eval_metric
๊ณผ์ ํฉ ํด๊ฒฐ ํ๋ผ๋ฏธํฐ
- eta ๊ฐ์ ๋ฎ์ถ๋ค (eta ๊ฐ ๋ฎ์ถ ๊ฒฝ์ฐ num_round ๊ฐ์ ๋์ฌ์ค์ผ ํจ
- max_depth ๊ฐ์ ๋ฎ์ถ๋ค
- min_child_weight ๊ฐ์ ๋์ธ๋ค
- gamma ๊ฐ์ ๋์ธ๋ค
- subsample๊ณผ colsample_bytree๋ฅผ ์กฐ์
์กฐ๊ธฐ ์ค๋จ
์ํ ์๋๋ฅผ ํฅ์์ํค๊ธฐ ์ํ ๊ธฐ๋ฅ
์์ธก ์ค๋ฅ๊ฐ ๋์ด์ ๊ฐ์ ๋์ง ์์ผ๋ฉด ๋ฐ๋ณต์ ๋๊น์ง ์ํํ์ง ์๊ณ ์ค์งํด ์ํ์๊ฐ์ ๊ฐ์ ํ ์ ์์
(1) ์กฐ๊ธฐ์ค๋จ์ ์ํํ๊ธฐ ์ํด์๋ ๋ณ๋์ ๊ฒ์ฆ์ฉ ๋ฐ์ดํฐ ํ์
์์ค์ฝ์ ์ ๋ฐฉ์ ๋ฐ์ดํฐ ์ธํธ์ 80%๋ฅผ ํ์ต์ฉ, 20%๋ฅผ ํ ์คํธ์ฉ์ผ๋ก ์ถ์ถํ ๋ค ํ์ต์ฉ ๋ฐ์ดํฐ์์ 90% ์ต์ข ํ์ต์ฉ, 10%๋ฅผ ๊ฒ์ฆ์ฉ์ผ๋ก ๋ถํ
(2) DMatrix
ํ์ต์ฉ, ๊ฒ์ฆ, ํ ์คํธ์ฉ ๋ฐ์ดํฐ ์ธํธ๋ฅผ ๋ชจ๋ ์ ์ฉ์ ๋ฐ์ดํฐ ๊ฐ์ฒด์ธ DMatrix๋ก ์์ฑ
# ๋ง์ฝ ๊ตฌ๋ฒ์ XGBoost์์ DataFrame์ผ๋ก DMatrix ์์ฑ์ด ์๋ ๊ฒฝ์ฐ X_train.values๋ก ๋ํ์ด ๋ณํ
# ํ์ต, ๊ฒ์ฆ, ํ
์คํธ์ฉ DMatrix๋ฅผ ์์ฑ
dtr = xgb.DMatrix(data=X_tr, label=y_tr)
dval = xgb.DMatrix(data=X_val, label=y_val)
dtest = xgb.DMatrix(data=X_test, label= y_test)
(3) ํ์ดํผ ํ๋ผ๋ฏธํฐ ์ค์
params = {'max_depth':3,
'eta': 0.05,
'objective': 'binary:logistic',
'eval_metric': 'logloss'
}
num_rounds = 400
(4) ์กฐ๊ธฐ์ค๋จ ์ํ
eval_metric ํ๊ฐ ์งํ(๋ถ๋ฅ์ผ ๊ฒฝ์ฐ logloss ์ ์ฉ)๋ก ํ๊ฐ์ฉ ๋ฐ์ดํฐ ์ธํธ์์ ์์ธก ์ค๋ฅ๋ฅผ ์ธก์
#ํ์ต ๋ฐ์ดํฐ ์
์ 'train' ๋๋ ํ๊ฐ๋ฐ์ดํฐ ์
์ 'eval'๋ก ๋ช
๊ธฐํฉ๋๋ค.
eval_list = [(dtr,'train'),(dval, 'eval')] # ๋๋ eval_list = [(dval, 'eval')]๋ง ๋ช
๊ธฐํด๋ ๋ฌด๋ฐฉ
#ํ์ดํผ ํ๋ผ๋ฏธํฐ์ early stopping ํ๋ผ๋ฏธํฐ๋ฅผ train() ํจ์์ ํ๋ผ๋ฏธํฐ๋ก ์ ๋ฌ
xgb_model = xgb.train(params = params, dtrain=dtr, num_boost_round=num_rounds, early_stopping_rounds=50, evals=eval_list)
[Output]
[0] train-logloss:0.65016 eval-logloss:0.66183
[1] train-logloss:0.61131 eval-logloss:0.63609
[2] train-logloss:0.57563 eval-logloss:0.61144
[3] train-logloss:0.54310 eval-logloss:0.59204
[4] train-logloss:0.51323 eval-logloss:0.57329
[5] train-logloss:0.48447 eval-logloss:0.55037
[6] train-logloss:0.45796 eval-logloss:0.52930
[7] train-logloss:0.43436 eval-logloss:0.51534
[8] train-logloss:0.41150 eval-logloss:0.49718
[9] train-logloss:0.39027 eval-logloss:0.48154
[10] train-logloss:0.37128 eval-logloss:0.46990
[11] train-logloss:0.35254 eval-logloss:0.45474
[12] train-logloss:0.33528 eval-logloss:0.44229
[13] train-logloss:0.31892 eval-logloss:0.42961
[14] train-logloss:0.30439 eval-logloss:0.42065
[15] train-logloss:0.29000 eval-logloss:0.40958
[16] train-logloss:0.27651 eval-logloss:0.39887
...
xgboost์ predict()๋ ์์ธก ๊ฒฐ๊ด๊ฐ์ด ์๋ ์์ธก ๊ฒฐ๊ณผ๋ฅผ ์ถ์ ํ ์ ์๋ ํ๋ฅ ๊ฐ์ ๋ฐํ
์์ธก ํ๋ฅ ์ด 0.5๋ณด๋ค ํฌ๋ฉด 1, ๊ทธ๋ ์ง ์์ผ๋ฉด 0์ผ๋ก ์์ธก๊ฐ์ ๊ฒฐ์ ํ๋ ๋ก์ง์ ์ถ๊ฐํ๋ฉด ๋จ
pred_probs = xgb_model.predict(dtest)
print('predict() ์ํ ๊ฒฐ๊ด๊ฐ์ 10๊ฐ๋ง ํ์, ์์ธก ํ๋ฅ ๊ฐ์ผ๋ก ํ์๋จ')
print(np.round(pred_probs[:10], 3))
#์์ธก ํ๋ฅ ์ด 0.5๋ณด๋ค ํฌ๋ฉด 1, ๊ทธ๋ ์ง ์์ผ๋ฉด 0์ผ๋ก ์์ธก๊ฐ ๊ฒฐ์ ํ์ฌ lsit ๊ฐ์ฒด์ธ preds์ ์ ์ฅ
preds = [1 if x >0.5 else 0 for x in pred_probs]
print('์์ธก๊ฐ 10๊ฐ๋ง ํ์:',preds[:10])
[Output]
predict() ์ํ ๊ฒฐ๊ด๊ฐ์ 10๊ฐ๋ง ํ์, ์์ธก ํ๋ฅ ๊ฐ์ผ๋ก ํ์๋จ
[0.845 0.008 0.68 0.081 0.975 0.999 0.998 0.998 0.996 0.001]
์์ธก๊ฐ 10๊ฐ๋ง ํ์: [1, 0, 1, 0, 1, 1, 1, 1, 1, 0]
plot_importance() ํด๋น ํผ์ฒ ์ค์๋ ๊ทธ๋ํ ์๊ฐํ
f ์ค์ฝ์ด๋ ํด๋น ํผ์ฒ๊ฐ ํธ๋ฆฌ ๋ถํ ์ ์ผ๋ง๋ ์์ฃผ ์ฌ์ฉ๋์๋ ์ง๋ฅผ ์งํ๋ก ๋ํ๋ธ ๊ฐ

cv() API๋ฅผ ํตํด ๋ฐ์ดํฐ ์ธํธ์ ๋ํ ๊ต์ฐจ ๊ฒ์ฆ ์ํํ ์ต์ ํ๋ผ๋ฏธํฐ๋ฅผ ๊ตฌํ ์ ์์
LightGBM ๊ฐ์ฅ ํฐ ์ฅ์ ์ XGBoost๋ณด๋ค ํ์ต์ ๊ฑธ๋ฆฌ๋ ์๊ฐ์ด ํจ์ฌ ์ ์. ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋๋ ์๋์ ์ผ๋ก ์ ์.
๋๋ถ๋ถ ๊ณผ์ ํฉ์ ๋ฐฉ์งํ๊ธฐ ์ํด ๊ท ํ ํธ๋ฆฌ ๋ถํ ๋ฐฉ์์ ์ฌ์ฉ
LightGBM์ ๋ฆฌํ ์ค์ฌ ํธ๋ฆฌ ๋ถํ ๋ฐฉ์์ ํธ๋ฆฌ์ ๊ท ํ์ ๋ง์ถ์ง ์๊ณ , ์ต๋ ์์ค ๊ฐ์ ๊ฐ์ง๋ ๋ฆฌํ๋
ธ๋๋ฅผ ์ง์์ ์ผ๋ก ๋ถํ
โ ๊ท ํ ํธ๋ฆฌ๋ถํ ๋ฐฉ์๋ณด๋ค ์์ธก ์ค๋ฅ ์์ค ์ต์ํ ๊ธฐ๋

LightGBM์ XGBoost ๋๋น ์ฅ์
- ๋ ๋น ๋ฅธ ํ์ต๊ณผ ์์ธก ์ํ ์๊ฐ
- ๋ ์์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋
- ์นดํ ๊ณ ๋ฆฌํ ํผ์ฒ์ ์๋ ๋ณํ
[์ฃผ์ ํ๋ผ๋ฏธํฐ]
num_iterations : ๋ฐ๋ณต์ํํ๋ ค๋ ํธ๋ฆฌ ๊ฐ์ ์ง์
learning_rate : ์
๋ฐ์ดํธ ๋๋ ํ์ต๋ฅ ๊ฐ
max_depth
min_data_leaf
num_leaves : ํ๋์ ํธ๋ฆฌ๊ฐ ๊ฐ์ง ์ ์๋ ์ต๋ ๋ฆฌํ ๊ฐ์
boosting
bagging_fraction : ๋ฐ์ดํฐ๋ฅผ ์ํ๋งํ๋ ๋น์จ ์ง์
feature_fraction : ๋ฌด์์๋ก ์ ํํ๋ ํผ์ฒ ๋น์จ
lambda_l2 : L2 regulation ์ ์ด๋ฅผ ์ํ ๊ฐ
lambda_l1 : L1 regulation ์ ์ด๋ฅผ ์ํ ๊ฐ
[Learning Task ํ๋ผ๋ฏธํฐ]
objective : ์ต์๊ฐ์ ๊ฐ์ ธ์ผ ํ ์์ค ํจ์ ์ ์
๊ณผ์ ํฉ ๋ฐฉ์ง ํ๋ผ๋ฏธํฐ
num_leaves์ต๋ ๋ฆฌํ ๊ฐ์ ์ ํmin_child_samplesmat_depth๋ช ์์ ์ผ๋ก ๊น์ด ํฌ๊ธฐ๋ฅผ ์ ํ
ํ์ด์ฌ ๋ํผ LightGBM๊ณผ ์ฌ์ดํท๋ฐ ๋ํผ XGBoost, LightGBM ํ์ดํผ ํ๋ฆฌ๋ฏธํฐ ๋น๊ต
<ํ ์ฌ์ง>
# LighttGBM์ ํ์ด์ฌ ํจํค์ง์ธ lightgbm์์ LGBMClassifier ์ํฌํธ
from lightgbm import LGBMClassifier
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
dataset = load_breast_cancer()
cancer_df = pd.DataFrame(data=dataset.data, columns=dataset.feature_names)
cancer_df['target']=dataset.target
X_features = cancer_df.iloc[:, :-1]
y_label = cancer_df.iloc[:,-1]
# ์ ์ฒด ๋ฐ์ดํฐ ์ค 80%๋ ํ์ต์ฉ ๋ฐ์ดํฐ, 20%๋ ํ
์คํธ์ฉ ๋ฐ์ดํฐ ์ถ์ถ
X_train, X_test, y_train, y_test = train_test_split(X_features, y_label, test_size=0.2, random_state=156)
# ์์์ ๋ง๋ X_train, y_train์ ๋ค์ ์ชผ๊ฐ์ 90%๋ ํ์ต๊ณผ 10%๋ ๊ฒ์ฆ์ฉ ๋ฐ์ดํฐ๋ก ๋ถ๋ฆฌ
X_tr, X_val, y_tr, y_val = train_test_split(X_train, y_train, test_size=0.1, random_state=156)
# ์์ XGBoost์ ๋์ผํ๊ฒ n_estimators๋ 400 ์ค์ .
lgbm_wrapper = LGBMClassifier(n_estimators=400, learning_rate=0.05)
# LightGBM๋ XGBoost์ ๋์ผํ๊ฒ ์กฐ๊ธฐ์ค๋จ ์ํ ๊ฐ๋ฅ
evals = [(X_tr, y_tr), (X_val, y_val)]
lgbm_wrapper.fit(X_tr, y_tr, early_stopping_rounds=50, eval_metric="logloss", eval_set=evals, verbose=True)
preds = lgbm_wrapper.predict(X_test)
pred_proba = lgbm_wrapper.predict_proba(X_test)[:,1]
[Output]
[1] training's binary_logloss: 0.625671 valid_1's binary_logloss: 0.628248
[2] training's binary_logloss: 0.588173 valid_1's binary_logloss: 0.601106
[3] training's binary_logloss: 0.554518 valid_1's binary_logloss: 0.577587
[4] training's binary_logloss: 0.523972 valid_1's binary_logloss: 0.556324
[5] training's binary_logloss: 0.49615 valid_1's binary_logloss: 0.537407
[6] training's binary_logloss: 0.470108 valid_1's binary_logloss: 0.519401
[7] training's binary_logloss: 0.446647 valid_1's binary_logloss: 0.502637
[8] training's binary_logloss: 0.425055 valid_1's binary_logloss: 0.488311
[9] training's binary_logloss: 0.405125 valid_1's binary_logloss: 0.474664
[10] training's binary_logloss: 0.386526 valid_1's binary_logloss: 0.461267
์ง๊ธ๊น์ง๋ ํ์ดํผ ํ๋ผ๋ฏธํฐ ํ๋์ ์ํด ์ฌ์ดํท๋ฐ์์ ์ ๊ณตํ๋ Grid Search ๋ฐฉ์์ ์ ์ฉ
๋ฒ ์ด์ง์ ์ต์ ํ๋ ๋ชฉ์ ํจ์ ์์ ์ ๋๋ก ์ ์ ์๋ ๋ธ๋ ๋ฐ์ค ํํ์ ํจ์์์ (์ต์ข ํจ์๋ฅผ ๋ชจ๋ฆ) ์ต๋ ๋๋ ์ต์ ํจ์ ๋ฐํ ๊ฐ์ ๋ง๋๋ ์ต์ ์ ๋ ฅ๊ฐ์ ๊ฐ๋ฅํ ์ ์ ์๋๋ฅผ ํตํด ๋น ๋ฅด๊ณ ํจ๊ณผ์ ์ผ๋ก ์ฐพ์์ฃผ๋ ๋ฐฉ์
๋ฒ ์ด์ง์ ์ต์ ํ
๋ฒ ์ด์ง์ ํ๋ฅ ์ ๊ธฐ๋ฐ์ ๋๊ณ ์๋ ์ต์ ํ ๊ธฐ๋ฒ.
๋์ฒด ๋ชจ๋ธ์ ํ๋ ํจ์๋ก๋ถํฐ ์ต์ ํจ์๋ฅผ ์์ธกํ ์ ์๋ ์ ๋ ฅ๊ฐ์ ์ถ์ฒ๋ฐ์ ๋ค ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ต์ ํจ์ ๋ชจ๋ธ์ ๊ฐ์ ํด ๋๊ฐ๋ฉฐ, ํ๋ํจ์๋ ๊ฐ์ ๋ ์์ธกํ ์ ์๋ ์ ๋ ฅ๊ฐ์ ์ถ์ฒ๋ฐ์ ๋ค ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ต์ ์ ๋ ฅ๊ฐ์ ๊ณ์ฐ

HyperOpt ์ฃผ์ ๋ก์ง โญ
1. ์ ๋ ฅ ๋ณ์๋ช ๊ณผ ์ ๋ ฅ๊ฐ์ ๊ฒ์๊ณต๊ฐ ์ค์
2. ๋ชฉ์ ํจ์์ ์ค์
3. ๋ชฉ์ ํจ์์ ๋ฐํ ์ต์๊ฐ์ ๊ฐ์ง๋ ์ต์ ์ ๋ ฅ๊ฐ์ ์ ์ถํ๋ ๊ฒ
(1) ์ ๋ ฅ ๋ณ์๋ช ๊ณผ ์ ๋ ฅ๊ฐ์ ๊ฒ์๊ณต๊ฐ ์ค์
{'์
๋ ฅ๋ณ์๋ช
': hp.quniform(label, low, high, q)}
from hyperopt import hp
# -10 ~ 10๊น์ง 1๊ฐ๊ฒฉ์ ๊ฐ์ง๋ ์
๋ ฅ ๋ณ์ X์ -15~15๊น์ง 1๊ฐ๊ฒฉ์ผ๋ก ์
๋ ฅ ๋ณ์ y ์ค์
search_space ={'x':hp.quniform('x', -10, 10, 1), 'y':hp.quniform('y', -15, 15, 1)}
(2) ๋ชฉ์ ํจ์๋ฅผ ์์ฑ
๋ชฉ์ ํจ์๋ ๋์ ๋๋ฆฌ๋ฅผ ์ธ์๋ก ๋ฐ๊ณ , ํน์ ๊ฐ์ ๋ฐํํ๋ ๊ตฌ์กฐ
from hyperopt import STATUS_OK
# ๋ชฉ์ ํจ์๋ฅผ ์์ฑ, ๋ณ์ซ๊ฐ๊ณผ ๋ณ์ ๊ฒ์ ๊ณต๊ฐ์ ๊ฐ์ง๋ ๋์
๋๋ฆฌ๋ฅผ ์ธ์๋ก ๋ฐ๊ณ , ํน์ ๊ฐ์ ๋ฐํ
def objective_func(search_space):
x= search_space['x']
y= search_space['y']
retval = x**2 - 20*y
return retval
๋ฐํ๊ฐ์ด ์ต์๊ฐ ๋ ์ ์๋ ์ต์ ์ ์ ๋ ฅ๊ฐ์ ์ฐพ์์ผ ๋จ
๐ fmin()
fmin(objective, space, algo, max_evals, trials)
space : ๊ฒ์ ๊ณต๊ฐ ๋์
๋๋ฆฌ
algo : ๋ฒ ์ด์ง์ ์ต์ ํ ์ ์ฉ ์๊ณ ๋ฆฌ์ฆ
max_evals : ์
๋ ฅ๊ฐ ์๋ ํ์
trials : (์ค์) ์ต์ ์
๋ ฅ๊ฐ์ ์ฐพ๊ธฐ ์ํด ์๋ํ ์
๋ ฅ๊ฐ ๋ฐ ํด๋น ์
๋ ฅ๊ฐ์ ๋ชฉ์ ํจ์ ๋ฐํ๊ฐ ๊ฒฐ๊ณผ๋ฅผ ์ ์ฅํ๋ ๋ฐ ์ฌ์ฉ๋จ
โ Trials ๊ฐ์ฒด
results๊ณผ val ์์ฑ ๊ฐ์ง
results, vals ์์ฑ์ ํตํด HyperOpt์ fmin() ํจ์์ ์ํ ์๋ง๋ค ์ต์ ํ๋๋ ๊ฒฝ๊ณผ๋ฅผ ๋ณผ ์ ์๋ ํจ์ ๋ฐํ๊ฐ๊ณผ ์
๋ ฅ ๋ณ์๊ฐ๋ค์ ์ ๋ณด๋ฅผ ์ ๊ณต
results
results๋ ๋ฐ๋ณต ์ํ ์๋ง๋ค ๋ฐํ
{'loss': ํจ์ ๋ฐํ๊ฐ, 'status': ๋ฐํ ์ํ๊ฐ}
vals
ํจ์์ ๋ฐ๋ณต ์ํ์๋ง๋ค ์
๋ ฅ๋๋ ์
๋ ฅ ๋ณ์๊ฐ์ ๊ฐ์ง
{'์
๋ ฅ๋ณ์๋ช
': ๊ฐ๋ณ ์ํ์๋ง๋ค ์
๋ ฅ๋ ๊ฐ ๋ฆฌ์คํธ}
์๊ณผ ๋ค๋ฅด๊ฒ ๋ชฉ์ ํจ์์์ XGBoost๋ฅผ ํ์ต์ํค๋ ์ฐจ์ด์
์ฃผ์ํด์ผ๋ ๋ถ๋ถ
(1) Objective func() ๋ง๋ค๊ธฐ
from sklearn.model_selection import cross_val_score
from xgboost import XGBClassifier
from hyperopt import STATUS_OK
# fmin()์์ ์
๋ ฅ๋ search_space ๊ฐ์ผ๋ก ์
๋ ฅ๋ ๋ชจ๋ ๊ฐ์ ์ค์ํ์.
# XGBClassifier์ ์ ์ํ ํ์ดํผ ํ๋ผ๋ฏธํฐ๋ ์ ์ํ ๋ณํ์ ํด์ค์ผ ํจ.
# ์ ํ๋๋ ๋์์๋ก ๋ ์ข์ ์์น์. -1 * ์ ํ๋๋ฅผ ๊ณฑํด์ ํฐ ์ ํ๋ ๊ฐ์ผ์๋ก ์ต์๊ฐ ๋๋๋ก ๋ณํ
def objective_func(search_space):
# ์ํ ์๊ฐ ์ ์ฝ์ ์ํด nestimators๋ 100์ผ๋ก ์ถ์
xgb_clf = XGBClassifier(n_estimators=100, max_depth=int(search_space['max_depth']),
min_child_weight=int(search_space['min_child_weight']),
learning_rate=search_space['learning_rate'],
colsample_bytree=search_space['colsample_bytree'],
eval_metric='logloss')
accuracy = cross_val_score(xgb_clf, X_train, y_train, scoring='accuracy', cv=3)
# accuracy๋ cv=3 ๊ฐ์๋งํผ roc-auc ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌ์คํธ๋ก ๊ฐ์ง. ์ด๋ฅผ ํ๊ท ํด์ ๋ฐํํ๋ -1์ ๊ณฑํจ.
return {'loss':-1 * np.mean(accuracy), 'status': STATUS_OK}
(2) fmin()์ ์ด์ฉํด ์ต์ ํ์ดํผ ํ๋ผ๋ฏธํฐ ๋์ถ
from hyperopt import fmin, tpe, Trials
trial_val = Trials()
best = fmin(fn=objective_func,
space=xgb_search_space,
algo=tpe.suggest,
max_evals=50, # ์ต๋ ๋ฐ๋ณต ํ์๋ฅผ ์ง์ ํฉ๋๋ค.
trials=trial_val, rstate=np.random.default_rng(seed=9))
print('best:', best)
(3) ๋์ถ๋ ์ต์ ํ์ดํผ ํ๋ผ๋ฏธํฐ๋ค์ ์ด์ฉํด XGBClassifier ์ฌํ์ต
xgb_wrapper = XGBClassifier(n_estimators=400,
learning_rate=round(best['learning_rate'], 5),
max_depth=int(best['max_depth']),
min_child_weight=int(best['min_child_weight']),
colsample_bytree=round(best['colsample_bytree'], 5)
)
evals = [(X_tr, y_tr), (X_val, y_val)]
xgb_wrapper.fit(X_tr, y_tr, early_stopping_rounds=50, eval_metric='logloss',
eval_set=evals, verbose=True)
preds = xgb_wrapper.predict(X_test)
pred_proba = xgb_wrapper.predict_proba(X_test)[:, 1]
get_clf_eval(y_test, preds, pred_proba)
[Output]
[0] validation_0-logloss:0.58942 validation_1-logloss:0.62048
[1] validation_0-logloss:0.50801 validation_1-logloss:0.55913
[2] validation_0-logloss:0.44160 validation_1-logloss:0.50928
[3] validation_0-logloss:0.38734 validation_1-logloss:0.46815
[4] validation_0-logloss:0.34224 validation_1-logloss:0.43913
[5] validation_0-logloss:0.30425 validation_1-logloss:0.41570
[6] validation_0-logloss:0.27178 validation_1-logloss:0.38953
[7] validation_0-logloss:0.24503 validation_1-logloss:0.37317
[8] validation_0-logloss:0.22050 validation_1-logloss:0.35628
[9] validation_0-logloss:0.19873 validation_1-logloss:0.33798
[10] validation_0-logloss:0.17945 validation_1-logloss:0.32463
[11] validation_0-logloss:0.16354 validation_1-logloss:0.31384
[12] validation_0-logloss:0.15032 validation_1-logloss:0.30607
Stacking ์์๋ธ
๊ฐ๋ณ ๋ชจ๋ธ๋ก ์์ธกํ ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๋ค์ ์ต์ข
์์ธก์ ์ํํ๋ ๋ฐฉ์
๋ค๋ฅธ ์์๋ธ๊ณผ์ ์ฐจ์ด์
์ฌ๋ฌ ๊ฐ๋ณ ๋ชจ๋ธ๋ค์ ์์ธก ๊ฒฐ๊ณผ๋ฅผ ํ์ตํด์ ์ต์ข
๊ฒฐ๊ณผ๋ฅผ ๋์ถํ๋ meta ๋ชจ๋ธ

๊ฐ๋ณ base ๋ชจ๋ธ
์ต์ข
meta ๋ชจ๋ธ : ๊ฐ๋ณ base ๋ชจ๋ธ์ ์์ธก ๊ฒฐ๊ณผ๋ฅผ ํ์ตํด ์ต์ข
๊ฒฐ๊ณผ๋ฅผ ๋
-> ์ด๋, ๊ฐ๋ณ ๋ชจ๋ธ์ ์์ธก ๊ฒฐ๊ณผ๋ฅผ stacking ํํ๋ก ๊ฒฐํฉํด์, ์ต์ข meta ๋ชจ๋ธ์ ์ ๋ ฅ์ผ๋ก ์ฌ์ฉ
1) Step 1 : ๊ฐ๋ณ base ๋ชจ๋ธ ํ์ต, ์์ธก๊ฐ ๋์ถ
ํ์ต ๋ฐ์ดํฐ๋ฅผ K๊ฐ์ fold๋ก ๋๋
K-1 ๊ฐ์ fold๋ฅผ ํ์ต ๋ฐ์ดํฐ๋ก ํ์ฌ base ๋ชจ๋ธ ํ์ต (K๋ฒ ๋ฐ๋ณต)
๊ฒ์ฆ fold 1๊ฐ๋ฅผ ์์ธกํ ๊ฒฐ๊ณผ (K fold) -> ์ต์ข
meta ๋ชจ๋ธ์ ํ์ต์ฉ ๋ฐ์ดํฐ
ํ
์คํธ ๋ฐ์ดํฐ๋ฅผ ์์ธกํ ๊ฒฐ๊ณผ (K๊ฐ) ์ ํ๊ท -> ์ต์ข
meta ๋ชจ๋ธ์ ํ
์คํธ์ฉ ๋ฐ์ดํฐ
2) Step 2 : ์ต์ข
meta ๋ชจ๋ธ ํ์ต
๊ฐ base ๋ชจ๋ธ์ด ์์ฑํ ํ์ต์ฉ ๋ฐ์ดํฐ๋ฅผ stacking -> ์ต์ข
meta ๋ชจ๋ธ์ ํ์ต์ฉ ๋ฐ์ดํฐ ์ธํธ
๊ฐ base ๋ชจ๋ธ์ด ์์ฑํ ํ
์คํธ์ฉ ๋ฐ์ดํฐ๋ฅผ stacking -> ์ต์ข
meta ๋ชจ๋ธ์ ํ
์คํธ์ฉ ๋ฐ์ดํฐ ์ธํธ
์ต์ข
ํ์ต์ฉ ๋ฐ์ดํฐ + ์๋ณธ ํ์ต ๋ ์ด๋ธ ๋ฐ์ดํฐ๋ก ํ์ต
์ต์ข
ํ
์คํธ์ฉ ๋ฐ์ดํฐ๋ก ์์ธก -> ์๋ณธ ํ
์คํธ ๋ ์ด๋ธ ๋ฐ์ดํฐ๋ก ํ๊ฐ