728x90
1.HyperParameter Tuning 방법
- Grid Search
- 모든 parameter로 학습 진행
- 데이터가 많아질수록 시간이 오래걸림
- HyperParameter가 3~4개 정도이고 데이터 세트가 작다면 효과적
- Random Search
- 정해진 격자 사이 값을 확률적으로 탐색
- 데이터가 많을 때 효과적
- Bayesian Optimization
- 수동 튜닝:
- 경험적으로 데이터 세트 내에서 여러번 모델의 HyperParameter를 튜닝하면서 선호하는 파라미터 기준으로 튜닝
HyperParameter Tuning의 주요 이슈
- Gradient Boosting 기반 알고리즘은 튜닝해야 할 HyperParameter 개수가 많고 범위가 넓어서 가능한 개별 경우의 수가 너무 많음
- 이러한 경우의 수가 많을 경우 데이터가 크면 HyperParameter 튜닝에 굉장히 오랜 시간이 투입되어야 함
Grid Search와 Random Search의 주요 이슈
- GridSearchCV는 수행시간이 너무 오래 걸림. 개별 HyperParameter들을 Grid 형태로 지정하는 것은 한계가 존재(Data Set가 작을 때 유리)
- RandomizedSearch는 수행 시간은 줄여주지만, Random한 선택으로 최적 하이퍼 파라미터 검출에 태생적 제약(Data Set가 클 때 유리)
- 두 가지 방법 모두 iteration 중에 어느정도 최적화된 HyperParameter들을 활용하면서 최적화를 수행할 수 없음
Bayesian Optimization가 필요한 순간
- 가능한 최소의 시도로 최적의 답을 찾아야 하는 경우
- 개별 시도가 너무 많은 시간/자원이 필요할 때
대용량 학습데이터에 하이퍼 파라미터 튜닝 시 Bayesian Optimization 이용
2.Bayesian Optimization (베이지안 최적화)
Bayesian Optimization: Acquisition Function / Surrogate Model / Function Optimization
베이지안 최적화는 목적함수 식을 제대로 알 수 없을 때, 최대 / 최소값을 만드는 최적해를 빠르게 찾아내는 최적화 방식
- 베이지안 최적화는 새로운 데이터를 입력 받았을 때 최적 함수를 예측하는 사후 모델을 개선해 나가면서 최적 함수를 도출
- 대체 모델(Surrogate Model)과 획득 함수(Acquisition Function)로 구성되며, 대체 모델이 획득 함수로부터 최적 입력값(하이퍼 라미터)을 추천 받은 뒤 이를 기반으로 최적 함수를 개선 / 추정(예측)
- 최적함수 모델을 추정할 때 일반적으로는 Gaussian Process 적용
- HyperOpt는 TPE(Tree - structure Parzen Estimator) 사용
- 획득 함수는 개선된 대체 모델을 기반으로 다시 최적 입력 값을 계산
Bayesian Optimization Process (베이지안 최적화 수행 단계)
1. 최초에는 랜덤하게 하이퍼 파라미터들을 샘플링하여 성능 결과를 관측
2. 관측된 값을 기반으로 대체 모델은 최적 함수를 예측 추정
- 최적 관측값: y축 value값이 가장 높은 값을 가질 때의 하이퍼 파라미터 값
- 신뢰구간: 추정된 함수의 결과값 오류 편차를 의미 -> 추정함수의 불확실성을 나타냄
3. 최적함수를 기반으로 획득 함수에서 다음으로 관측할 하이퍼 파라미터 추출
- 획득함수는 이전의 최적 관측값보다 더 큰 최댓값을 가질 가능성이 높은 지점의 하이퍼 파라미터를 대체 모델에 전달
4. 해당 하이퍼 파라미터로 관측된 값을 기반으로 대체 모델은 다시 최적 함수 예측 추정
- 2 ~ 4단계를 반복하면서 대체모델의 불확실성 개선 -> 더욱 정확한 최적 함수 모델 추정
베이지안 최적화 구현 요소
1. 입력 값 범위
- Search_space = {'x' : (-10,10), 'y' : (-15,15)}
2. 함수
- F라는 함수는 x,y 라는 Seach_space를 입력으로 받아서 출력은 z로 반환
- def black_box_function(x, y): return -x**2 - 20*y
3. 함수 반환 최소값/최대값을 만드는 최적 입력값 유추
- fmin(fn=black_box_function, space=search_space, algo=tpe.suggest, max_evals=20, trials=trial_val)
3. Bayesian Optimization Package (HyperOpt)
베이지안 최적화를 머신러닝 모델의 하이퍼 파라미터 튜닝에 적용할 수 있게 제공되는 패키지
베이지안 최적화를 구현한 주요 패키지:
1. HyperOpt
- 대표적인 알고리즘: TPE (Tree Parzen Estimation)기반, ATPE, GP
- HyperOpt 자체는 HyperParameter 튜닝이 아니라 함수의 최소값을 찾아내는 기능을 하기에 응용하여 최적의 HyperParameter를 찾아내는 코드를 짠다
2.Bayesian optimization
3.Optuna
4. HyperOpt
주요 로직
- 검색 공간(Search Space) 설정
- 목적 함수(Objective Function) 설정
- 목적 함수의 반환 최소값을 가지는 최적 입력값 찾기
- HyperOpt는 목적 함수의 반환값의 최소값을 가지는 최적 입력값을 유추함
- HyperParameter 튜닝 (HyperOpt는 함수의 최소값을 만드는 최적해를 찾아내는 기능 ONLY, 튜닝은 X)
HyperOpt를 통한 최적화 예시
from hyperopt import hp
Search Space (입력 값 범위)
- 여러 개의 입력 변수들과 이들 값의 범위를 지정, { 입력 변수 값 : 입력 변수 검색 범위 }
- 입력 변수 검색 범위
- hp.quniform(label, low, high, q): label로 지정된 입력 값 변수 검색 공간을 최소값 low에서 최대값 high까지 q의 간격을 가지고 설정
- hp.uniform(label, low, high): 최소값 low에서 최대값 high까지 정규 분포 형태의 검색 공간 설정
- hp.randint(label, upper): 0부터 최대값 upper까지 random한 정수 값으로 검색 공간 설정
- hp.loguniform(label, low, high): uniform 함수에서 log 변환, exp(low)에서 exp(high)까지 exp(uniform(low, high))값을 반환하며 반환 값의 log 변환된 값은 정규 분포 형태를 가지는 검색 공간 설정
- 0.1부터 0.2까지 로그 변환된 값이 정규 분포 형태를 가지도록 설정
- hp.loguniform('learning_rate' , np.log(0.1), np.log(0.2))
- hp.choice(label, options): 검색값이 문자열 / 문자열 + 숫자값인 경우 설정 (Options는 리스트나 튜플 형태로 제공됨)
search_space = {'x' : hp.quniform('x', 5, 15, 1), 'y' : hp.quniform('y', 0.01, 0.1)}
목적 함수
- search_space를 입력 받아 로직에 따라 loss 값을 계산하고 이를 반환하는 함수
- 반드시 dictionary 형태의 값을 반환하고 {'loss':함수 반환값, 'status':반환 상태값} 와 같이 키 값을 설정해서 반환해야 함
- 목적 함수 안에 classifier( ) 객체나 regressor( ) 객체를 하이퍼 파라미터를 받아 생성
[주의점]
- 특정 하이퍼 파라미터는 정수값만 입력가능
- Parameter를 Search Space에서 입력받을 때: 입력된 모든 값이 실수형이므로 정수형 Parameter는 int( )를 통해 정수형 변환을 해줘야 함
- HyperOpt의 목적함수는 최소값을 반환할 수 있도록 최적화 필요
- 만약 return하는 성능 평가지표가 높을 수록 더 좋은 수치라면 -1 * (성능 평가지표)하여 성능 평가지표가 클수록 loss가 최소가 되도록 반환
- 분류모델의 성능 평가지표는 높을수록 좋은 수치이기 때문에 앞에 (-1)을 곱해준다
- 회귀모델의 성능 평가지표는 낮을수록 좋은 수치이기 때문에 그대로 둔다
def objective_func(search_space):
x = search_space['x']
y = search_space['y']
print('x:', x, 'y:', y)
return {'loss' : x**2 + y*20, 'status' : STATUS_OK}
목적 함수의 반환 최소값을 만드는 최적해 찾기
- 목적 함수를 실행하여 최소 반환값(loss)를 최적으로 찾아내는 함수
- Bayesian 최적화 기법으로 입력 변수들의 search space 상에서 정해진 횟수만큼 입력 변수들을 입력하여 목적 함수의 반환 값(loss)를 최적으로 찾아냄
- hyperopt는 이를 위해 fmin() 함수를 제공
fmin(fn=objective_func, space=search_space, algo=algo, max_evals, trials)
- 최적의 상태의 파라미터 값을 dictionary 형태로 반환
- fn: 목적함수
- space: search space
- algo: 베이지안 최적화 적용 알고리즘
- tpe.suggest를 default로 넣는다 (HyperOpt의 기본 최적화 알고리즘인 TPE의미)
- max_evals: 최적화 시도 횟수 (최적 입력값을 찾기 위한 입력값 시도 횟수)
- trials: 최적화 로그 기록 객체 (함수의 반복 수행 시마다 입력되는 변수값과 변환값을 속성으로 가지고 있음)
- trial_val = Trials()
- trial_val.results: obejctive function의 return 값이 python list 안에 {'loss':함수 반환값, 'status':반환 상태값} 형태로 들어감
- trial_val.vals: {'입력변수명':개별 수행 시마다 입력된 값 리스트} 형태로 저장
- trial_val.result의 접근: 각 시행의 loss 반환값 가져오기
c = [loss_dict["loss"] for loss_dict in trial_val.results]
- trial_val의 접근: 각 시행의 하이퍼 파리미터값 가져오기
x = trial_val.vals["max_depth"]
y = trial_val.vals["learning_rate"]
- rstate: 동일한 결과값을 가질 수 있도록 설정하는 seed
- random seed 값으로 고정
- rstate를 설정 안하는 것이 경험적으로 더 높은 성능을 반환한다
best = fmin(fn=objective_func, space=search_space, algo=algo, max_evals=5, trials=trials)
HyperOpt의 주요 구성 요소
5. HyperOpt 기본 실습
HyperOpt를 통한 최적화 예시
- Search Space: 입력 값 범위 지정
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)}
search_space
# {'x': <hyperopt.pyll.base.Apply at 0x12c5ad550>,
# 'y': <hyperopt.pyll.base.Apply at 0x12c5ad7d0>}
- Objective Function (목적함수) 생성
- 최종 함수를 정확하게 알 수는 없다
- 이 경우 이해를 위해 예제로서 미리 준 것
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 # return {'loss': retval, 'status':STATUS_OK}
- 목적함수의 최소값을 찾는 함수
from hyperopt import fmin, tpe, Trials
import numpy as np
# 입력 결괏값을 저장한 Trials 객체값 생성.
trial_val = Trials()
# 목적 함수의 최솟값을 반환하는 최적 입력 변숫값을 5번의 입력값 시도(max_evals=5)로 찾아냄.
best_01 = fmin(
fn=objective_func,
space=search_space,
algo=tpe.suggest,
max_evals=5,
trials=trial_val,
rstate=np.random.default_rng(seed=0),
)
print("best:", best_01)
# 100%|██████████| 5/5 [00:00<00:00, 101.02trial/s, best loss: -224.0]
# best: {'x': -4.0, 'y': 12.0}
- max_evals(최적화 시도횟수)를 20으로 증가
trial_val = Trials()
# max_evals를 20회로 늘려서 재테스트
best_02 = fmin(
fn=objective_func,
space=search_space,
algo=tpe.suggest,
max_evals=20,
trials=trial_val,
rstate=np.random.default_rng(seed=0),
)
print("best:", best_02)
# 100%|██████████| 20/20 [00:00<00:00, 1182.88trial/s, best loss: -296.0]
# best: {'x': 2.0, 'y': 15.0}
trial_val
# <hyperopt.base.Trials at 0x7f8211e0bd90>
HyperOpt 수행 시 적용된 입력 값들과 목적 함수 반환 값 보기
- trials: 최적화 로그 기록 객체
- trial_val = Trials()
- trial_val.results: obejctive function의 return 값이 python list 안에 {'loss':함수 반환값, 'status':반환 상태값} 형태로 들어감
- trial_val.vals: {'입력변수명':개별 수행 시마다 입력된 값 리스트} 형태로 저장
- fmin( )에 인자로 들어가는 Trials 객체의 result 속성에 python list로 목적 함수 반환값들이 저장됨
- 리스트 내부의 개별 원소는 {'loss':함수 반환값, 'status':반환 상태값} 와 같은 딕셔너리임
# fmin( )에 인자로 들어가는 Trials 객체의 result 속성에 파이썬 리스트로 목적 함수 반환값들이 저장됨
# 리스트 내부의 개별 원소는 {'loss':함수 반환값, 'status':반환 상태값} 와 같은 딕셔너리임.
print(trial_val.results)
# [{'loss': -64.0, 'status': 'ok'}, {'loss': -184.0, 'status': 'ok'}, {'loss': 56.0, 'status': 'ok'}, {'loss': -224.0, 'status': 'ok'}, {'loss': 61.0, 'status': 'ok'}, {'loss': -296.0, 'status': 'ok'}, {'loss': -40.0, 'status': 'ok'}, {'loss': 281.0, 'status': 'ok'}, {'loss': 64.0, 'status': 'ok'}, {'loss': 100.0, 'status': 'ok'}, {'loss': 60.0, 'status': 'ok'}, {'loss': -39.0, 'status': 'ok'}, {'loss': 1.0, 'status': 'ok'}, {'loss': -164.0, 'status': 'ok'}, {'loss': 21.0, 'status': 'ok'}, {'loss': -56.0, 'status': 'ok'}, {'loss': 284.0, 'status': 'ok'}, {'loss': 176.0, 'status': 'ok'}, {'loss': -171.0, 'status': 'ok'}, {'loss': 0.0, 'status': 'ok'}]
- Trials 객체의 vals 속성에 {'입력변수명':개별 수행 시마다 입력된 값 리스트} 형태로 저장됨.
# Trials 객체의 vals 속성에 {'입력변수명':개별 수행 시마다 입력된 값 리스트} 형태로 저장됨.
print(trial_val.vals)
# {'x': [-6.0, -4.0, 4.0, -4.0, 9.0, 2.0, 10.0, -9.0, -8.0, -0.0, -0.0, 1.0, 9.0, 6.0, 9.0, 2.0, -2.0, -4.0, 7.0, -0.0], 'y': [5.0, 10.0, -2.0, 12.0, 1.0, 15.0, 7.0, -10.0, 0.0, -5.0, -3.0, 2.0, 4.0, 10.0, 3.0, 3.0, -14.0, -8.0, 11.0, -0.0]}
- DataFrame의 column에 x, y, losses을 설정
import pandas as pd
# results에서 loss 키값에 해당하는 밸류들을 추출하여 list로 생성.
losses = [loss_dict['loss'] for loss_dict in trial_val.results]
# DataFrame으로 생성.
result_df = pd.DataFrame({'x': trial_val.vals['x'],
'y': trial_val.vals['y'],
'losses': losses
}
)
result_df
6. HyperOpt를 이용한 XGBoost HyperParameter 튜닝
import pandas as pd
import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import warnings
warnings.filterwarnings('ignore')
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_tr, X_val, y_tr, y_val= train_test_split(X_train, y_train,
test_size=0.1, random_state=156 )
- Search Space 설정
from hyperopt import hp
# max_depth는 5에서 20까지 1간격으로, min_child_weight는 1에서 2까지 1간격으로
# colsample_bytree는 0.5에서 1사이, learning_rate는 0.01에서 0.2사이 정규 분포된 값으로 검색.
xgb_search_space = {'max_depth': hp.quniform('max_depth', 5, 20, 1),
'min_child_weight': hp.quniform('min_child_weight', 1, 2, 1),
'learning_rate': hp.uniform('learning_rate', 0.01, 0.2),
'colsample_bytree': hp.uniform('colsample_bytree', 0.5, 1)
}
- Objective Function 설정
- fmin()에서 입력된 search_space값으로 입력된 모든 값은 실수형임
- XGBClassifier의 정수형 하이퍼 파라미터는 정수형 변환을 해줘야 함
- 정확도는 높은 수록 더 좋은 수치임. -1* 정확도를 곱해서 큰 정확도 값일 수록 최소가 되도록 변환
- 분류모델의 성능 평가지표는 높을수록 좋은 수치이기 때문에 앞에 (-1)을 곱해준다
- 회귀모델의 성능 평가지표는 낮을수록 좋은 수치이기 때문에 그대로 둔다
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):
# 수행 시간 절약을 위해 n_estimators는 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 개수만큼의 정확도 결과를 가지므로 이를 평균해서 반환하되 -1을 곱해줌.
return {"loss": -1 * np.mean(accuracy), "status": STATUS_OK}
- 목적함수의 최소값을 찾는 함수
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)
- 최적 하이퍼 파라미터 반올림 처리
print('colsample_bytree:{0}, learning_rate:{1}, max_depth:{2}, min_child_weight:{3}'.format(
round(best['colsample_bytree'], 5), round(best['learning_rate'], 5),
int(best['max_depth']), int(best['min_child_weight'])))
# colsample_bytree:0.5483, learning_rate:0.18403, max_depth:18, min_child_weight:2
- 최적 하이퍼 파라미터로 XGBoost로 재학습
- HyperOpt 자체는 HyperParameter 튜닝이 아니라 함수의 최소값을 찾아내는 기능 -> 따로 HyperParameter 튜닝을 해줘야함
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)
[0] validation_0-logloss:0.54472 validation_1-logloss:0.58675
[1] validation_0-logloss:0.44155 validation_1-logloss:0.52577
[2] validation_0-logloss:0.36542 validation_1-logloss:0.48906
[3] validation_0-logloss:0.30756 validation_1-logloss:0.45704
[4] validation_0-logloss:0.26142 validation_1-logloss:0.41671
[5] validation_0-logloss:0.22616 validation_1-logloss:0.39605
[6] validation_0-logloss:0.19465 validation_1-logloss:0.37095
[7] validation_0-logloss:0.16951 validation_1-logloss:0.36066
[8] validation_0-logloss:0.14718 validation_1-logloss:0.34686
[9] validation_0-logloss:0.13006 validation_1-logloss:0.33716
[10] validation_0-logloss:0.11635 validation_1-logloss:0.32332
[11] validation_0-logloss:0.10455 validation_1-logloss:0.32074
[12] validation_0-logloss:0.09388 validation_1-logloss:0.31916
[13] validation_0-logloss:0.08434 validation_1-logloss:0.30987
[14] validation_0-logloss:0.07702 validation_1-logloss:0.30469
[15] validation_0-logloss:0.07144 validation_1-logloss:0.30293
[16] validation_0-logloss:0.06649 validation_1-logloss:0.29610
[17] validation_0-logloss:0.06119 validation_1-logloss:0.29303
[18] validation_0-logloss:0.05693 validation_1-logloss:0.28973
[19] validation_0-logloss:0.05291 validation_1-logloss:0.28781
[20] validation_0-logloss:0.04951 validation_1-logloss:0.28757
[21] validation_0-logloss:0.04603 validation_1-logloss:0.28904
[22] validation_0-logloss:0.04376 validation_1-logloss:0.28744
[23] validation_0-logloss:0.04113 validation_1-logloss:0.29028
[24] validation_0-logloss:0.03932 validation_1-logloss:0.28659
[25] validation_0-logloss:0.03741 validation_1-logloss:0.29059
[26] validation_0-logloss:0.03570 validation_1-logloss:0.28740
[27] validation_0-logloss:0.03416 validation_1-logloss:0.28613
[28] validation_0-logloss:0.03309 validation_1-logloss:0.28441
[29] validation_0-logloss:0.03165 validation_1-logloss:0.28617
[30] validation_0-logloss:0.03059 validation_1-logloss:0.28501
[31] validation_0-logloss:0.02961 validation_1-logloss:0.28505
[32] validation_0-logloss:0.02881 validation_1-logloss:0.28319
[33] validation_0-logloss:0.02801 validation_1-logloss:0.28407
[34] validation_0-logloss:0.02710 validation_1-logloss:0.27684
[35] validation_0-logloss:0.02654 validation_1-logloss:0.27599
[36] validation_0-logloss:0.02591 validation_1-logloss:0.27329
[37] validation_0-logloss:0.02514 validation_1-logloss:0.26722
[38] validation_0-logloss:0.02484 validation_1-logloss:0.26668
[39] validation_0-logloss:0.02424 validation_1-logloss:0.26733
[40] validation_0-logloss:0.02404 validation_1-logloss:0.26721
[41] validation_0-logloss:0.02374 validation_1-logloss:0.26519
[42] validation_0-logloss:0.02351 validation_1-logloss:0.26809
[43] validation_0-logloss:0.02295 validation_1-logloss:0.27016
[44] validation_0-logloss:0.02272 validation_1-logloss:0.26844
[45] validation_0-logloss:0.02252 validation_1-logloss:0.27126
[46] validation_0-logloss:0.02233 validation_1-logloss:0.26975
[47] validation_0-logloss:0.02214 validation_1-logloss:0.26975
[48] validation_0-logloss:0.02175 validation_1-logloss:0.27071
[49] validation_0-logloss:0.02157 validation_1-logloss:0.26926
[50] validation_0-logloss:0.02122 validation_1-logloss:0.27124
[51] validation_0-logloss:0.02087 validation_1-logloss:0.27159
[52] validation_0-logloss:0.02070 validation_1-logloss:0.27435
[53] validation_0-logloss:0.02054 validation_1-logloss:0.27227
[54] validation_0-logloss:0.02040 validation_1-logloss:0.27114
[55] validation_0-logloss:0.02025 validation_1-logloss:0.26898
[56] validation_0-logloss:0.02012 validation_1-logloss:0.27039
[57] validation_0-logloss:0.01998 validation_1-logloss:0.26914
[58] validation_0-logloss:0.01983 validation_1-logloss:0.27181
[59] validation_0-logloss:0.01970 validation_1-logloss:0.27142
[60] validation_0-logloss:0.01956 validation_1-logloss:0.26793
[61] validation_0-logloss:0.01945 validation_1-logloss:0.26890
[62] validation_0-logloss:0.01932 validation_1-logloss:0.26558
[63] validation_0-logloss:0.01922 validation_1-logloss:0.26380
[64] validation_0-logloss:0.01908 validation_1-logloss:0.26627
[65] validation_0-logloss:0.01896 validation_1-logloss:0.26761
[66] validation_0-logloss:0.01885 validation_1-logloss:0.26726
[67] validation_0-logloss:0.01874 validation_1-logloss:0.26420
[68] validation_0-logloss:0.01863 validation_1-logloss:0.26519
[69] validation_0-logloss:0.01852 validation_1-logloss:0.26755
[70] validation_0-logloss:0.01841 validation_1-logloss:0.26766
[71] validation_0-logloss:0.01831 validation_1-logloss:0.26738
[72] validation_0-logloss:0.01821 validation_1-logloss:0.26560
[73] validation_0-logloss:0.01811 validation_1-logloss:0.26778
[74] validation_0-logloss:0.01802 validation_1-logloss:0.26628
[75] validation_0-logloss:0.01792 validation_1-logloss:0.26601
[76] validation_0-logloss:0.01782 validation_1-logloss:0.26490
[77] validation_0-logloss:0.01773 validation_1-logloss:0.26706
[78] validation_0-logloss:0.01764 validation_1-logloss:0.26707
[79] validation_0-logloss:0.01755 validation_1-logloss:0.26798
[80] validation_0-logloss:0.01745 validation_1-logloss:0.26496
[81] validation_0-logloss:0.01736 validation_1-logloss:0.26459
[82] validation_0-logloss:0.01728 validation_1-logloss:0.26434
[83] validation_0-logloss:0.01719 validation_1-logloss:0.26527
[84] validation_0-logloss:0.01710 validation_1-logloss:0.26244
[85] validation_0-logloss:0.01702 validation_1-logloss:0.26336
[86] validation_0-logloss:0.01694 validation_1-logloss:0.26229
[87] validation_0-logloss:0.01686 validation_1-logloss:0.26193
[88] validation_0-logloss:0.01678 validation_1-logloss:0.26243
[89] validation_0-logloss:0.01671 validation_1-logloss:0.26481
[90] validation_0-logloss:0.01663 validation_1-logloss:0.26362
[91] validation_0-logloss:0.01656 validation_1-logloss:0.26339
[92] validation_0-logloss:0.01650 validation_1-logloss:0.26328
[93] validation_0-logloss:0.01643 validation_1-logloss:0.26328
[94] validation_0-logloss:0.01636 validation_1-logloss:0.26216
[95] validation_0-logloss:0.01629 validation_1-logloss:0.25971
[96] validation_0-logloss:0.01623 validation_1-logloss:0.26199
[97] validation_0-logloss:0.01616 validation_1-logloss:0.26191
[98] validation_0-logloss:0.01609 validation_1-logloss:0.26160
[99] validation_0-logloss:0.01603 validation_1-logloss:0.26073
[100] validation_0-logloss:0.01597 validation_1-logloss:0.26073
[101] validation_0-logloss:0.01591 validation_1-logloss:0.26052
[102] validation_0-logloss:0.01584 validation_1-logloss:0.26109
[103] validation_0-logloss:0.01579 validation_1-logloss:0.26323
[104] validation_0-logloss:0.01573 validation_1-logloss:0.26322
[105] validation_0-logloss:0.01568 validation_1-logloss:0.26228
[106] validation_0-logloss:0.01562 validation_1-logloss:0.26241
[107] validation_0-logloss:0.01555 validation_1-logloss:0.26004
[108] validation_0-logloss:0.01550 validation_1-logloss:0.25928
[109] validation_0-logloss:0.01544 validation_1-logloss:0.25986
[110] validation_0-logloss:0.01538 validation_1-logloss:0.25964
[111] validation_0-logloss:0.01533 validation_1-logloss:0.25758
[112] validation_0-logloss:0.01527 validation_1-logloss:0.25775
[113] validation_0-logloss:0.01522 validation_1-logloss:0.25833
[114] validation_0-logloss:0.01517 validation_1-logloss:0.25828
[115] validation_0-logloss:0.01512 validation_1-logloss:0.25797
[116] validation_0-logloss:0.01507 validation_1-logloss:0.26003
[117] validation_0-logloss:0.01502 validation_1-logloss:0.25929
[118] validation_0-logloss:0.01497 validation_1-logloss:0.25928
[119] validation_0-logloss:0.01493 validation_1-logloss:0.25928
[120] validation_0-logloss:0.01487 validation_1-logloss:0.25726
[121] validation_0-logloss:0.01483 validation_1-logloss:0.25923
[122] validation_0-logloss:0.01479 validation_1-logloss:0.25943
[123] validation_0-logloss:0.01474 validation_1-logloss:0.25939
[124] validation_0-logloss:0.01469 validation_1-logloss:0.25746
[125] validation_0-logloss:0.01465 validation_1-logloss:0.25768
[126] validation_0-logloss:0.01461 validation_1-logloss:0.25703
[127] validation_0-logloss:0.01457 validation_1-logloss:0.25761
[128] validation_0-logloss:0.01452 validation_1-logloss:0.25755
[129] validation_0-logloss:0.01448 validation_1-logloss:0.25695
[130] validation_0-logloss:0.01444 validation_1-logloss:0.25694
[131] validation_0-logloss:0.01440 validation_1-logloss:0.25884
[132] validation_0-logloss:0.01436 validation_1-logloss:0.25713
[133] validation_0-logloss:0.01432 validation_1-logloss:0.25716
[134] validation_0-logloss:0.01428 validation_1-logloss:0.25690
[135] validation_0-logloss:0.01425 validation_1-logloss:0.25694
[136] validation_0-logloss:0.01421 validation_1-logloss:0.25750
[137] validation_0-logloss:0.01417 validation_1-logloss:0.25745
[138] validation_0-logloss:0.01414 validation_1-logloss:0.25686
[139] validation_0-logloss:0.01410 validation_1-logloss:0.25660
[140] validation_0-logloss:0.01406 validation_1-logloss:0.25843
[141] validation_0-logloss:0.01403 validation_1-logloss:0.25847
[142] validation_0-logloss:0.01400 validation_1-logloss:0.25844
[143] validation_0-logloss:0.01396 validation_1-logloss:0.25898
[144] validation_0-logloss:0.01393 validation_1-logloss:0.25828
[145] validation_0-logloss:0.01390 validation_1-logloss:0.25802
[146] validation_0-logloss:0.01387 validation_1-logloss:0.25825
[147] validation_0-logloss:0.01383 validation_1-logloss:0.25993
[148] validation_0-logloss:0.01380 validation_1-logloss:0.25935
[149] validation_0-logloss:0.01377 validation_1-logloss:0.25931
[150] validation_0-logloss:0.01374 validation_1-logloss:0.25866
[151] validation_0-logloss:0.01370 validation_1-logloss:0.25870
[152] validation_0-logloss:0.01368 validation_1-logloss:0.25894
[153] validation_0-logloss:0.01365 validation_1-logloss:0.25868
[154] validation_0-logloss:0.01362 validation_1-logloss:0.25801
[155] validation_0-logloss:0.01359 validation_1-logloss:0.25750
[156] validation_0-logloss:0.01356 validation_1-logloss:0.25803
[157] validation_0-logloss:0.01353 validation_1-logloss:0.25799
[158] validation_0-logloss:0.01350 validation_1-logloss:0.25962
[159] validation_0-logloss:0.01347 validation_1-logloss:0.25966
[160] validation_0-logloss:0.01344 validation_1-logloss:0.25904
[161] validation_0-logloss:0.01342 validation_1-logloss:0.25930
[162] validation_0-logloss:0.01339 validation_1-logloss:0.25879
[163] validation_0-logloss:0.01336 validation_1-logloss:0.25875
[164] validation_0-logloss:0.01333 validation_1-logloss:0.26031
[165] validation_0-logloss:0.01331 validation_1-logloss:0.26007
[166] validation_0-logloss:0.01329 validation_1-logloss:0.25962
[167] validation_0-logloss:0.01326 validation_1-logloss:0.25964
[168] validation_0-logloss:0.01324 validation_1-logloss:0.26111
[169] validation_0-logloss:0.01321 validation_1-logloss:0.26049
[170] validation_0-logloss:0.01319 validation_1-logloss:0.26052
[171] validation_0-logloss:0.01317 validation_1-logloss:0.26029
[172] validation_0-logloss:0.01314 validation_1-logloss:0.26079
[173] validation_0-logloss:0.01312 validation_1-logloss:0.26035
[174] validation_0-logloss:0.01310 validation_1-logloss:0.26013
[175] validation_0-logloss:0.01308 validation_1-logloss:0.26039
[176] validation_0-logloss:0.01306 validation_1-logloss:0.26031
[177] validation_0-logloss:0.01303 validation_1-logloss:0.25974
[178] validation_0-logloss:0.01301 validation_1-logloss:0.26021
[179] validation_0-logloss:0.01299 validation_1-logloss:0.25980
[180] validation_0-logloss:0.01297 validation_1-logloss:0.26005
[181] validation_0-logloss:0.01295 validation_1-logloss:0.25997
[182] validation_0-logloss:0.01294 validation_1-logloss:0.26040
[183] validation_0-logloss:0.01292 validation_1-logloss:0.26016
[184] validation_0-logloss:0.01290 validation_1-logloss:0.25977
[185] validation_0-logloss:0.01288 validation_1-logloss:0.25927
[186] validation_0-logloss:0.01286 validation_1-logloss:0.25951
[187] validation_0-logloss:0.01284 validation_1-logloss:0.25943
[188] validation_0-logloss:0.01283 validation_1-logloss:0.25921
[189] validation_0-logloss:0.01282 validation_1-logloss:0.25883
오차 행렬
[[34 3]
[ 3 74]]
정확도: 0.9474, 정밀도: 0.9610, 재현율: 0.9610, F1: 0.9610, AUC:0.9923
- DataFrame으로 시각화
losses = [loss_dict["loss"] for loss_dict in trial_val.results]
result_df = pd.DataFrame(
{
"max_depth": trial_val.vals["max_depth"],
"min_child_weight": trial_val.vals["min_child_weight"],
"colsample_bytree": trial_val.vals["colsample_bytree"],
"learning_rate": trial_val.vals["learning_rate"],
"losses": losses,
}
)
result_df
728x90