LoginSignup
13
17

More than 3 years have passed since last update.

【XGboost】ハイパラメータを自動で最適化

Last updated at Posted at 2019-10-21

はじめに

東京23区の賃料を予測する回帰モデルをXGboostで作成しています。
モデルを作成するときにパラメータのチューニングで苦戦して色々と調べたので、この記事にまとめます。

機械学習に関して特別知識があるわけではないため、間違いを含んでいるかもしれません。その際はコメント欄で指摘していただけると助かります。

チューニングの方法として有名なものでグリッドサーチやベイズの最適化という手法があるのですが、精度や即効性の観点から今回はOptunaというハイパラメータ最適化ツールを利用して最適化してみました。
Optunaはベイズ最適化アルゴリズムの一種を利用したハイパーパラメータチューニングのフレームワークです

Google「ベイズの最適化」

チューニングすべきとされるハイパラメータ

そもそもどの値をチューニングすべきなのか?

XGboostのモデル作成においてチューニングすべきとされるハイパラメータの一覧です。

パラメータ デフォルト 内容 よく取る値
eta 0.3 学習率を調整。小さくするとより頑健になる 0.01~0.2
max_depth 6 木の深さの最大値。過学習を制御する。 3,4,5, ... 10
min_child_weight 1 子ノードにおいて観察されるデータの重み付けの合計値の最小の値
subsample 1 各木においてランダムに抽出される列の割合 0.5~1
colsample_bytree 1 各レベル単位での、分割における列のsubsample比率 0.5~1
lambda 1 重みに関するL2正則化項
alpha 0 重みに関するL1正則化項

Optunaでチューニングしてみる

今回は5つのパラメータn_estimatorsmax_depthmin_child_weightsubsamplecolsample_bytreeをOptunaを用いてチューニングしていきます。

方針

  1. 最適化したいパラメータを選択。
    この時の注意点としてはパラメータを増やすことによって処理に必要な時間が指数関数的に増える。そのため、できるだけ少ないパラメータを選択する。

  2. 最小化したい目的関数を定義
    今回は回帰タスクなので、MSE(平均二乗誤差)を目的関数として最小化を行う。
    Optunaは目的関数の最小化しかできないので、確率など最大化したいものは1-xや1/xなどを目的関数とする。

  3. 最適化の実行

  4. 結果を出力
    最適化されたパラメータの値や、最小化された目的関数の値を確認することができる。

実際のコード

Optunaのインストール

$ pip install optuna

Optunaのインポート

import optuna

ハイパラメータの指定と目的関数の作成
具体的なパラメータの指定方法は新しい項目を設けて記している。

def opt(trial):
    # パラメータの指定
    n_estimators = trial.suggest_int('n_estimators', 0, 1000)
    max_depth = trial.suggest_int('max_depth', 1, 20)
    min_child_weight = trial.suggest_int('min_child_weight', 1, 20)
    subsample = trial.suggest_discrete_uniform('subsample', 0.5, 0.9, 0.1)
    colsample_bytree = trial.suggest_discrete_uniform('colsample_bytree', 0.5, 0.9, 0.1)
    # XGBostのインスタンス生成
    xgboost_tuna = XGBRegressor(
        random_state=42,
        n_estimators = n_estimators,
        max_depth = max_depth,
        min_child_weight = min_child_weight,
        subsample = subsample,
        colsample_bytree = colsample_bytree,
    )
    # 学習
    xgboost_tuna.fit(X_train,y_train)
    # 予測
    tuna_pred_test = xgboost_tuna.predict(X_test)
    # MSEを返す
    return np.sqrt(mean_squared_error(y_test, tuna_pred_test))

最適化
最適化を実行する時に試行回数を指定できる。

# studyオブジェクトの作成
study = optuna.create_study()
# 最適化の実行
study.optimize(opt, n_trials=50)

結果の確認

# 最適パラメータの表示
print(study.best_params)
# 最小化された目的関数を表示
print(study.study.best_value)

最適化の続行
先ほど試行を50回行い、今回50回行うので合計で100回試行を行ったことになる。

study.optimize(objective, n_trials=50)

パラメータの指定方法

Optunaが対応しているデータ型は5つ。データ型によってパラメータの指定方法が異なるので1つずつみていく。

  1. Categorical parameter:カテゴリー型パラメーター
    optimizer = trial.suggest_categorical('optimizer', ['MomentumSGD', 'Adam'])
    第一引数でパラメーターの名前、第二引数でリスト型で値を指定する。

  2. Int parameter:整数値型パラメーター
    num_layers = trial.suggest_int('num_layers', 1, 3)
    第一引数でパラメーターの名前、第二・第三引数に指定した数値の間でパラメーターをチューニング。

  3. Uniform parameter:浮動小数点型パラメーター
    dropout_rate = trial.suggest_uniform('dropout_rate', 0.0, 1.0)
    第一引数でパラメーターの名前、第二・第三引数に指定した数値の間でパラメーターをチューニング。

  4. Loguniform parameter:対数型パラメーター
    learning_rate = trial.suggest_loguniform('learning_rate', 1e-5, 1e-2)
    第一引数でパラメーターの名前、第二・第三引数に指定した数値の間でパラメーターをチューニング。

  5. Discrete-uniform parameter:離散値型パラメーター
    drop_path_rate = trial.suggest_discrete_uniform('drop_path_rate', 0.0, 1.0, 0.1)
    第一引数でパラメーターの名前、第二引数以降で値を指定する。

参考サイト

Optuna公式ドキュメント
新米データサイエンティストのFXブログ

13
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
17