본문 바로가기
ML/ML-Kaggle, 데이콘

Bayesian Optimization

by lucian 2021. 12. 16.

한글로 베이지안 최적화 이다. 어렵다... 기본틀만 이해하자.

 

하이퍼 파라미터의 다양한 튜닝 방법 중 grid optimization, random optimization 다음으로 bayesian optimization이다.

저번 포스트인 랜덤포레스트에서 그리드 최적화로 적절한 하이퍼 파라미터를 찾은적이 있다.

https://lucian-blog.tistory.com/44?category=1002577 

 

랜덤포레스트(RandomForestRegressor)

앙상블 기법 - 배깅, 부스팅, 랜덤포레스트 등의 기법 중 랜덤포레스트에 대해 알아보자. 랜덤포레스트는 의사결정나무를 여러개를 모아다 합쳐놓은 것이다. 일종의 배깅인데, 각 의사결정나무

lucian-blog.tistory.com

 

 

그리드 최적화는 내가 설정한 값들의 모든 조합을 바탕으로 최고의 성능을 찾아내주는 방법이다.

그렇기에 모든 하이퍼파라미터 조합을 찾고 그 시간이 오래 걸린다. 또한 성능이 최고점이 아닐 가능성이 있다. 왜냐면 내가 설정한 범위, 간격 내에서 하이퍼파라미터 조합을 찾기 때문이다.

 

반면에 베이지안 최적화는 사전정보를 가지고 최적화 값을 탐색하는 방법이다.

베이지안 최적화도 비슷하지만 조금 다르다. 하이퍼파라미터의 범위를 지정 후, Random하게 R번 탐색한 후 B번 만큼 최적의 값을 찾아간다. 즉 random하게 찍은 값들이 적으면 최적값을 찾는게 불가능하다. 이것은 만약 하이퍼파라미터의 범위가 넓어지면 최적값을 찾는게 어려워진다. 그렇기에 DL처럼 하이퍼파라미터 범위가 넓고 데이터가 많은 곳에는 쓰이기가 어렵다.

https://dacon.io/competitions/open/235698/talkboard/403915?page=1&dtype=recent

 

먼저 베이지안 최적화에서 알아야 할 친구들이 두가지가 있다.

Surrogate model과 Acquisition function 이다.

 

  • Surrogate model
    - ML의 결과 (x1, f(x1)) (x2, f(x2)) ...의 값들과 하이퍼 파라미터를 토대로 목적함수를 추정하는 모델이다. 
    - 이 surrogate model은 가우시안 프로세스(GP) 활용해서 정규분포의 확률변수를 얻어내는 함수라 할 수 있음.

  • Acquisition function
    - Surrogate model을 할용해서 다음의 탐색지점을 설정해줌. 
    - 즉 목적함수를 잘 추정하기 위한 입력값을 추천해주는 함수이다. 보통 Expected Imporvement를 사용.
     

https://blog.naver.com/PostView.nhn?blogId=dpfkdlt&logNo=221678800067&from=search&redirect=Log&widgetTypeCall=true&directAccess=false

여기서

검은점선 : 실제 목적함수

검은실선 : Surrogate Model이 추정한 함수의 평균

파란영역 : surrogate model의 표준편차

초록실선 : Acquision function

이다.

 

 

우리는 실제 목적함수를 추정하여 새로운 목적함수를 만들었다.(surrogate Model)

그 중 실제 목적함수(검은점선)과 우리가 만든 새로운 목적함수(검은실선)가 겹치는 부분 중 최고점들을 찾아냈다.(제일 최적화된것이라 추측된 부분)

그 중 오른쪽 점이 가장 높으므로 가장 최적화가 잘 되어있는 부분이다. 하지만 파란영역안에 이 오른쪽 점보다 높은 부분이 있다는 것을 알게되었다.(=acquision function의 acquision max point)

이것을 반영해서 새로운 목적함수를 만든다.(surrogate Model)

 

최종적으로 검은실선과 검은점선이 만나는 점들 중 가장 높은점 그리고 파란영역보다 높은 점이 최적화지점이다. 

이 지점의 하이퍼파라미터가 이 모델에서 최적화된 하이퍼파라미터라는 것.

 

 

즉 베이지안 최적화는

우리가 ML으로 모델을 만들었다면 그 모델을 사전정보라 한다.

이 모델과 하이퍼파라미터를 통해 새로운 미지의 목적함수(surrogate model)을 만들고 이 미지의 목적함수를 진짜 목적함수와 같게하기 위해 acquisition function을 사용해 조정한다. 그 과정에서 하이퍼파라미터들의 최적값을 찾는다.

 

 

이 베이지안 최적화는 매우 복잡한 문제를 해결하기 위한 알고리즘은 아니라고 한다.

그래서 DL에선 못쓰고 ML에서 사용한다. ML을 위한 ML이라고 하는 것 같다.

 

이제 이 정도로 이해하고 코딩부분으로 넘어가보자.


이 부분은 베이지안 최적화 방법을 진행하기 위해 데이터를 전처리하는 과정임.
최적화방법만 볼 경우 밑으로 넘기기.

# 데이터 다운로드 링크로 데이터를 코랩에 불러옵니다.

!wget 'https://bit.ly/3i4n1QB'

import zipfile
with zipfile.ZipFile('3i4n1QB', 'r') as existing_zip:
    existing_zip.extractall('data')
import pandas as pd

from sklearn.preprocessing import MinMaxScaler, OneHotEncoder
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import KFold, train_test_split
from sklearn.metrics import accuracy_score

import numpy as np
train=pd.read_csv('data/train.csv')
test=pd.read_csv('data/test.csv')


# scaling
scaler=MinMaxScaler()
train['scaled fixed acidity']=scaler.fit_transform(train[['fixed acidity']])
test['scaled fixed acidity']=scaler.fit_transform(teest[['fixed acidity']])

#encoding
encoder=OneHotEncoder()
encoder.fit(train[['type']])

onehot=encoder.transform(train[['type']])
onehot=onehot.toarray()
onehot=pd.DataFrame(onehot)
onehot.columns=encoder.get_feature_names()
train=pd.concat([train,onehot],axis=1)
train=train.drop(columns=['type'])

onehot = encoder.transform(test[['type']])
onehot = onehot.toarray()
onehot = pd.DataFrame(onehot)
onehot.columns = encoder.get_feature_names()
test = pd.concat([test, onehot], axis = 1)
test = test.drop(columns = ['type'])

이제 데이터 전처리했으면 베이지안 최적화를 진행해보자. 랜덤포레스트의 하이퍼파라미터들을 베이지안 최적화로 가장 성능이 좋은 하이퍼파라미터를 찾을 것이다.

# 베이지안 최적화를 설치하고 불러온다.
!pip install bayesian-optimization



from bayes_opt import BayesianOptimization

 

다음으로 베이지안 최적화를 시작하기 전에 준비해야 되는 것들이 있다.

1. 베이지안 최적화에 들어갈 목적함수를 만들어준다.

2. 베이지안 최적화에서 하이퍼 파라미터의 범위를 지정해준다.

# 1.목점함수를 만든다. 
BO_rf(max_depth, n_estimators):
	rf_params={
    		'max_depth':(1,3), # 랜덤포레스트의 하이퍼파라미터. 의사결정나무의 깊이를 설정
            'n_estimators':(30,100), #랜덤포레스트의 하이퍼파라미터. 의사결정나무의 갯수를 설정
            }
            
    rf=RandomForestClassifier(**rf_params)
    
    X_train,X_valid,y_train,y_valid=train_test_split(X,y,test_size=0.2)
    
    rf.fit(X_train,y_train)
    
    score=accuracy_score(y_valid,rf.predict(X_valid))
    
    return score
# 2. 하이퍼 파라미터 범위를 dict 형태로 설정해준다.
# 전에도 말했지만 최적화를 할때 하이퍼 파라미터의 이름이 틀리면 오류가 생긴다.

pbounds={
	'max_depth':(1,3),
    'n_estimators:(30,100),
    }

 

이제 베이지안 최적화를 불러와준다.

베이지안 최적화를 불러올 때, 방금 위에서 만든 목점함수와 범위가 들어간다.

# f 인자는 탐색 대상 함수를 선택해준다. 아까 위에서 만든 함수가 이에 해당
# pbounds 인자는 하이퍼파라미터의 범위를 설정해준다.
# verbose 인자는 결과값을 print해줄것이냐에 대해 설정해준다. (디폴트가 2이고 2는 전체를 print, 1은 최대만, 0은 print하지 않음)

BO_rf=BayesianOptimization(f=rf_bo, pbounds=pbounds, random_state=0, verbose=2)

 

 

이제 베이지안 최적화를 진행한다. maximize함수를 사용해서 최적화 값을 찾아준다.

# init_points인자는 초기 random으로 몇개의 값을 찾을것인지
# n_iter 인자는 추가로 조사할 값들을 몇개 찾을지 설정해준다.
# 즉 여기서 찾을 point는 init_points+n_iter 로 총 10개의 최적화 point를 찾아준다.
BO_rf.maximize(init_points=5, n_iter=5)

verbose를 2로 해서 전체 과정이 print된 것을 볼 수 있다.

 

 

 

 

 

이제 최적화 과정이 끝났다. 가장 최적화가 잘되는 하이퍼 파라미터를 불러와보자. max함수를 써서 가져올 수 있다.

print(BO_rf.max)

max_params=BO_rf.max['params']
print(max_params)

max_params['max_depth']=int(max_params['max_depth'])
max_params['n_estimators']=int(max_params['n_estimator'])
print(max_params)

 

 

마지막으로 이제 최적화된 하이퍼 파라미터를 진짜 모델에 넣어준다.

BO_tuend_rf=RandomForestClassifier(**max_params)

 

 

 

 

 

 

 

베이지안 최적화의 함수들의 인자들 설명은 이 포스트를 보고 참고했다.

https://sualab.github.io/introduction/practice/2019/04/01/bayesian-optimization-overview-2.html

 

Bayesian Optimization 개요: 딥러닝 모델의 효과적인 hyperparameter 탐색 방법론 (2)

(이전 포스팅 보기)

sualab.github.io

 

'ML > ML-Kaggle, 데이콘' 카테고리의 다른 글

다중공산성 해결 방법  (0) 2021.12.29
다중공산성  (0) 2021.12.17
Hold-out, 교차검증(K-Flod), Stratified K-fold  (0) 2021.12.09
GBM(Gradient Boosting Model)  (0) 2021.10.08
EDA  (0) 2021.10.08

댓글