본문 바로가기

파이썬/전처리

베이지안 최적화(optimization) 개념 Auto Ml로 하이퍼파라미터 튜닝하기

모델 성능 향상을 위해서 필요한 하이퍼파라미터 튜닝,

Auto ML로 Hyperparameter Optimization이 가능하다.

 

 

Hyperparameter Optimization은 크게 그리드서치, 랜덤서치, 베이지안 옵티마이제이션 3가지가 있다.

 

※참고

하이퍼파라미터 튜닝 방법1. - 그리드 서치

 

 

그리드 서치는 파라미터 값을 직접 지정해줘야 한다는 번거로움이 있어 실제로는 베이지안 최적화 방식을 많이 사용한다. 물론 베이지안 옵티마이제이션이 무조건 최고다! 라는건 아니지만 Auto ML 영역에서 소요 시간이나 성능 등을 고려하면 다른 하이퍼파라미터 튜닝 방법에 비해서 좋다고 할 수 있다.

 

 

 

베이지안 옵티마이제이션 개념

 

사실 파이썬 초보인 나에게 이 개념은 너무너무 어렵고 헷갈린다..

그래서 틀린 부분이 있을 수 있지만 우선 정리해본다. (틀린 부분이 있다면 댓글로 알려주신다면 감사하겠습니다)

 

 

베이지안 최적화는 미지의 목적함수(blank-box function)을 최대화 혹은 최소화하는 최적해를 찾는 기법이다. Surrogate model(대체모델)과 Acquisition function으로 구성되어 있다.

 

 

*Surrogate model

:현재까지 조사된 입력값-함수값 쌍들에 대해 목적 함수에 대한 확률적 추정을 수행하는 모델

 

*Acquisition function

: Surrogate model을 활용해 다음 입력값 후보를 추천해주는 함수

 

 

t=2, t-3, t=4 이렇게 순차적으로 수행하는데 베이지안 최적화는 그리드서치나 랜덤서치와 달리 사전분포를 활용한다. 사전 분포를 이용하면 보다 더 나은 성능을 도출하는 하이퍼파라미터를 찾을 수 있다.

 

 

파란색 실선은 목적함수, 검정색 점선은 예측값, 하늘색 색칠된 영역은 목적함수가 있을 법한 영역이다.

EI(x)는 Acquisition function을 의미하며 별표는 다음 후보지점이다.

 

 

입력값-함수값의 조합을 기반으로 Surrogate model을 만들고 순차적으로 업데이트 하다보면 예측값과 실제 함수값이 거의 유사해지는 순간이 온다. 그 지점 중 최적값을 argmin(x)로 선택하는 것이다.

 

 

 

베이지안 최적화 실습 코드

 

우선 Bayesian-Optimization 설치부터 해준다.

나중에 import할 때는 BayesianOptimizaion으로 호출한다. (가운데에 - 없음)

!pip install Bayesian-Optimization

 

예제에서는 lgbm을 목적함수로 사용했다. lightGBM에 대한 자세한 내용은 아래 포스팅 참고

 

※참고

2021.07.11 - [파이썬/머신러닝] - light GBM이란? 파라미터 설명과 코드 실습

 

light GBM이란? 파라미터 설명과 코드 실습

LightGBM은 XGBoost에 비해 훈련 시간이 짧고 성능도 좋아 부스팅 알고리즘에서 가장 많은 주목을 받고 있다. GradientBoosting을 발전시킨 것이 XGBoost, 여기서 속도를 더 높인 것이 LightGBM이다. ※참고 부

for-my-wealthy-life.tistory.com

 

from sklearn.metrics import make_scorer, roc_auc_score
from sklearn.model_selection import cross_validate
import lightgbm as lgb
from bayes_opt import BayesianOptimization


#목적함수 생성
#실수형 값들이 들어올 수 있으므로 정수형 하이퍼파라미터는 정수형으로 변경해줘야 함

def lgbm_cv(learning_rate, num_leaves, max_depth, min_child_weight, colsample_bytree, 
            feature_fraction, bagging_fraction, lambda_l1, lambda_l2):
    model = lgb.LGBMClassifier(learning_rate=learning_rate,
                                n_estimators = 1000, #고정값
                                #boosting = 'dart',
                                num_leaves = int(round(num_leaves)),
                                max_depth = int(round(max_depth)),
                                min_child_weight = int(round(min_child_weight)),
                                colsample_bytree = colsample_bytree,
                                feature_fraction = max(min(feature_fraction, 1), 0),
                                bagging_fraction = max(min(bagging_fraction, 1), 0),
                                lambda_l1 = max(lambda_l1, 0),
                                lambda_l2 = max(lambda_l2, 0)
                               )
    scoring = {'roc_auc_score': make_scorer(roc_auc_score)}
    result = cross_validate(model, X, y, cv=5, scoring=scoring)
    auc_score = result["test_roc_auc_score"].mean()
    return auc_score
    
# 입력값의 탐색 대상 구간
pbounds = {'learning_rate' : (0.01, 0.05),
           'num_leaves': (300, 600),
           'max_depth': (2, 25),
           'min_child_weight': (30, 100),
           'colsample_bytree': (0, 0.99),
           'feature_fraction': (0.0001, 0.99),
           'bagging_fraction': (0.0001, 0.99),
           'lambda_l1' : (0, 0.99),
           'lambda_l2' : (0, 0.99),
          }
 
#f: 목적함수, pbounds:입력값의 탐색구간
lgbmBO = BayesianOptimization(f = lgbm_cv, pbounds = pbounds, verbose = 2, random_state = 42 )
#목적함수가 최대가 되는 최적해 찾기(acq=ei)
lgbmBO.maximize(init_points=5, n_iter = 20, acq='ei', xi=0.01)