Recent Posts
Recent Comments
Link
Today
Total
12-28 17:06
관리 메뉴

Hippo's data

하이퍼파라미터(Hyperparameter) 튜닝 - optuna 본문

ML(Machine Learning)

하이퍼파라미터(Hyperparameter) 튜닝 - optuna

Hippo's data 2024. 3. 16. 22:25
728x90

데이터분석의 대표 플랫폼인 캐글에서 인플루언서분들의 코드를 보다보면 optuna를 이용하여 하이퍼파라미터 튜닝을 하는 것을 종종 볼 수 있는데욥 오늘은 하이퍼파라미터(Hyperparameter) 튜닝 방법 중 하나인 optuna에 대해 알아보겠습니다!

# 하이퍼파라미터란?

먼저 optuna에 대해 알아보기 전에 하이퍼파라미터에 대해 알아보겠습니다

하이퍼파라미터란 사용자가 직접 설정하는 값으로 직접 모델의 학습방식을 조절할 수 있습니다

쉬운 예시로 경사 하강법에서의 학습률(learning rate) , epoch 에포크 수, k-NN(k 최근접 이웃) 모델의 k값 등이 있는데욥

 

이러한 하이퍼파라미터를 조절하며 사용자는 모델의 성능을 올릴 수 있습니다!

 

하이퍼파라미터를 조절하는 것을 하이퍼파라미터(Hyperparameter) 튜닝이라고 부르는데요

그리드서치, 랜덤서치 등 또한 이에 해당합니다!

https://hipposdata.tistory.com/47

 

하이퍼파라미터(Hyperparameter) 튜닝 - 그리드서치, 랜덤서치

모델의 성능을 향상하는 방법은 여러가지가 있습니다 학습데이터를 깔끔하게 정제/전처리하거나 중요한 변수들을 선택(Feature selection)하는 등 다양한 방법이 있는데요 그중 오늘은 모델의 하이

hipposdata.tistory.com

 

# optuna 작동방식

목적함수 정의 

모델이 향상시키려고 하는 목적함수 값을 설정합니다 ex)roc_auc, accuracy 등등

 

탐색할 하이퍼파라미터 공간 정의

suggest_float, suggest_int, suggest_categorical를 이용하여 연속형, 정수형, 범주형 하이퍼파라미터를 각각 정의

 

스터디 객체 생성 및 최적화 실행

optuna는 study라는 객체에 각 시행마다의 결과값들이 저장됩니다

 

 

# 코드로 구현

대표적인 ML알고리즘인 랜덤포레스트의 최적의 하이퍼파라미터를 찾는 코드를 구현해보겠습니다!

최적값을 찾을때 KFold를 추가해 보았습니다

#optuna 설치
!pip install optuna
# 라이브러리 불러오기
import numpy as np
import optuna
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score, StratifiedKFold

def objective(trial):
    # 하이퍼파라미터 범위 설정 
    n_estimators = trial.suggest_int('n_estimators', 10, 3000)
    max_depth = trial.suggest_int('max_depth', 2, 128)
    min_samples_split = trial.suggest_float('min_samples_split', 0.001, 0.5)
    min_samples_leaf = trial.suggest_float('min_samples_leaf', 0.001, 0.5)

    # 랜덤 포레스트 분류 모델 생성
    model = RandomForestClassifier(
        n_estimators=n_estimators,
        max_depth=max_depth,
        min_samples_split=min_samples_split,
        min_samples_leaf=min_samples_leaf,
        random_state=42
    )
        # 교차 검증 설정
    cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
   
    # 교차 검증을 사용한 모델 평가 / 목적함수 정의
    scores = cross_val_score(model, X_train, y_train, cv=cv, scoring='roc_auc')
    accuracy = np.mean(scores)
   
    return accuracy
# Optuna 스터디 객체 생성 
study = optuna.create_study(direction='maximize')
# 최적화 실행 / 탐색 횟수 설정 
study.optimize(objective, n_trials=50)

 

-> 요런식으로 탐색이 끝날때마다 시간, 탐색한 횟수, 시도한 하이퍼파라미터 값, 현재까지 최고의 시행이 아래 출력됩니다! 

[I 2024-03-12 19:53:41,081] Trial 100 finished with value: 0.6797211448663709 and parameters: {'n_estimators': 2297, 'max_depth': 96, 'min_samples_split': 0.29747028284184107, 'min_samples_leaf': 0.13717893196685516}. Best is trial 41 with value: 0.814270849812625.
[I 2024-03-12 19:53:44,173] Trial 101 finished with value: 0.8126972496806207 and parameters: {'n_estimators': 360, 'max_depth': 109, 'min_samples_split': 0.24302501717307537, 'min_samples_leaf': 0.013474474555970345}. Best is trial 41 with value: 0.814270849812625.

# 결과 출력
print('완료된 trial의 수:', len(study.trials))
print('최적의 파라미터:', study.best_trial.params)
print('최적의 지표 점수:', study.best_value)

 

# study 객체 저장 및 불러온 후 이어서 탐색

optuna 시행을 여러번 나눠서 탐색하기 위해 결과가 저장된 study객체를 pkl형식으로 저장 후 불러와서 이어서 탐색을 진행할 수 있습니다

import pickle
study_name = "optuna_rf_100"  # 스터디 이름
study_file_path = f"../optuna_model/{study_name}.pkl"  # 스터디 객체를 저장할 파일 경로
data = pd.read_csv('../open/train.csv')

# 스터디 객체를 파일로 저장
with open(study_file_path, "wb") as f:
    pickle.dump(study, f)
# 저장한 스터디 객체를 불러오기
with open(study_file_path, "rb") as f:
        study = pickle.load(f)
print("스터디 객체를 파일에서 불러왔습니다.")
# 이어서 탐색 진행
study.optimize(objective, n_trials=100)

 

 

자세한 내용은 공식 깃허브 문서를 보면 알 수 있습니다!

https://github.com/optuna/optuna

 

GitHub - optuna/optuna: A hyperparameter optimization framework

A hyperparameter optimization framework. Contribute to optuna/optuna development by creating an account on GitHub.

github.com

728x90