fantom_zona’s diary

Impact the world!!!

Cross validation + OptunaでMLPのモデル選択してみた話

やったこと

とあるテーブルコンペに出た時に, sklearnのMLPRegressorを使ってみました.
完全に素人がやってみた内容なので, 是非ともアドバイスください.

コード内容

optunaは最小化のためのパラメータ調整ライブラリらしいです.
sklearnのKFoldと合わせて使ってみました.

import pandas as pd
import numpy as np 
from sklearn.model_selection import KFold
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import r2_score


import lightgbm as lgb
import optuna

以下で, objectという関数を定義します. objectはパラメータを含む関数で, 関数内で調整するパラメータを明示的に記述する必要があります. optunaはobjectの出力を最小化します. 今回は決定係数でモデルの評価をしてみました. "X_"がinput, "y_"というのがoutputです.

kf = KFold(n_splits = 5, shuffle = True, random_state = 0)

def objective(trial):
    '''
    trial:set of hyperparameter    
    '''
    # hyper params
    max_layer_size = trial.suggest_int('hidden_layer_sizes', 50, 300)
    activation_func = trial.suggest_categorical('activation', ['relu', 'tanh'])
    alpha = trial.suggest_loguniform('alpha', 1e-5, 1e-3)
 
    # model
    model = MLPRegressor(hidden_layer_sizes=(max_layer_size, ),
                                 activation = activation_func,
                                  alpha=alpha)
    
    MLP_scores = []
    for train_index, test_index in kf.split(X_):
        X_train, X_test = X_[train_index], X_[test_index]
        y_train, y_test = y_[train_index], y_[test_index]

        model = MLPRegressor(hidden_layer_sizes=(max_layer_size, ),
                                 activation = activation_func,
                                  alpha=alpha)
        model.fit(X_train, y_train)
        y_pred = model.predict(X_test)
        MLP_scores.append(r2_score(y_test, y_pred))
        print("max_layer_size :", max_layer_size)
        print("activation_func :", activation_func)
        print("alpha :", alpha)
        print("result :", r2_score(y_test, y_pred))

 
    score =-np.mean(MLP_scores)  #optunaは最小化なので符号を反転させる.
    return score

関数を定義後, optunaを動かします.

study = optuna.create_study()
study.optimize(func=objective, # 実行する関数
               n_trials=20, 
               timeout=None, #default: None
               n_jobs=-1 #multiprocess
              )