scikit-learn - 13(베이지안 최적화 / HyperOpt)

안동균·2024년 11월 11일

베이지안 최적화

새로운 데이터를 입력받았을 때 최적 함수를 예측하는 사후 모델을 개선해 나가며 최적 함수 모델을 만들어냄

획득 함수 : 개선된 대체 모델을 기반으로 최적 입력값 계산

대체 모델 : 획득 함수로부터 최적 함수를 예측할 수 있는 입력값을 추천 받은 뒤 최적 함수 모델을 개선해 나감


사용법

  1. 입력 변수 명과 입력값의 검색 공간 설정
  2. 목적 함수 설정
  3. 반환 최솟값을 가지는 최적 입력값 유추

검색 공간

from hyperopt import hp
search_space = {'x': hp.quniform('x', -10, 10, 1), 
				'y': hp.quniform('y', -15, 15, 1) } 

검색 공간 활용 메소드

hp.quniform(label, low, high, q) : 최소부터 최대 까지 q의 간격을 가지는 검색 공간

hp.uniform(label, low, high) : 최소부터 최대까지 정규 분포 형태의 검색 공간

hp.randint(label. upper) : 0부터 최대까지 random한 정수로 검색 공간

hp.loguniform(label, low, high) : 반환 값을 log화 하여 정규 분포 형태를 가진 검색 공간


목적 함수

변수와 변수 검색 공간을 가지는 dictionary를 인자로 받고 특정 값 반환

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

최적값 유추(HyperOpt fmin)

parameter

fn : objective_func와 같은 목적함수

space : search_space와 같은 검색 공간

algo : 베이지안 최적화 적용 알고리즘

max_evals : 최적 입력값을 찾기 위한 입력값 시도 횟수

trials : 최적 입력값을 찾기 위해 시도한 입력값 및 목적함수 반환 결과 저장

rstate : random_state와 같은 것

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)

예제

데이터 분리(훈련, 테스트, 검증)

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 )

검색 공간 설정

from hyperopt import hp

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),
                   }

검색 공간에서 목적 함수로 입력되는 모든 인자는 실수형 값
=> 정수로 형 변환을 해줘야함

HyperOpt의 목적 함수는 최소값을 반환함
=> -1을 곱해줘야 함
ex) 목적 함수의 반환값을 정확도로 계산
0.8% 보단 0.9%가 높으나 최소값을 반환, 80이 더 좋은 최적화로 판단
-1을 곱할 경우 -0.8, -0.9가 되므로 -0.9 반환


목적 함수

from sklearn.model_selection import cross_val_score
from xgboost import XGBClassifier
from hyperopt import STATUS_OK

def objective_func(search_space):
    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)
    
    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)

최적값
colsample_bytree : 0.5
learning_rate : 0.19
max_depth : 15
min_child_weight : 1

0개의 댓글