スポンサーリンク

Optunaチューニング

Python

LightGBMの最適なパラメータを求める際にOptunaが便利です。指定した条件内で最も精度が良くなるパラメータを設定してくれます。

Optunaチューニング

データセット

import numpy as np
import pandas as pd
from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split

data = load_diabetes()
df = pd.DataFrame(data.data, columns = data.feature_names)
df["label"] = data.target

train, valid = train_test_split(df, test_size = 0.1)

load_diabetesで回帰予測をしましょう。

チューニングなしで学習

import lightgbm as lgbm

feat_cols = [c for c in df.columns if c != "label"]
train_X = train[feat_cols]
valid_X = valid[feat_cols]
train_y = train["label"]
valid_y = valid["label"]
train_ds = lgbm.Dataset(train_X, train_y)
valid_ds = lgbm.Dataset(valid_X, valid_y)

params = {"objective": "regression", "verbose": -1}

results = {}
model = lgbm.train(
    params = params,
    train_set = train_ds,
    num_boost_round = 100,
    valid_sets = [train_ds, valid_ds],
    valid_names = ["train", "valid"],
    callbacks = [lgbm.log_evaluation(10), lgbm.record_evaluation(results)]
)

デフォルトのパラメータで学習します。

import matplotlib.pyplot as plt
plt.figure(figsize = (12, 4))
plt.plot(results["train"]["l2"])
plt.plot(results["valid"]["l2"])
plt.show()

from sklearn.metrics import r2_score
r2_score(valid_y, model.predict(valid_X))
# 0.4662953855094151

R2スコアは0.466であまり良くないですね。

Optunaチューニング

# !pip install optuna
import optuna

def objective(trial):
    params = {
        "objective": "regression",
        "verbose": -1,
        "lambda_l1": trial.suggest_float("lambda_l1", 1e-8, 10.0, log = True),
        "lambda_l2": trial.suggest_float("lambda_l2", 1e-8, 10.0, log = True),
        "num_leaves": trial.suggest_int("num_leaves", 2, 256),
    }

    model = lgbm.train(
        params = params,
        train_set = train_ds,
        num_boost_round = 100,
        valid_sets = [train_ds, valid_ds],
        valid_names = ["train", "valid"],
    )
    score = r2_score(valid_y, model.predict(valid_X))
    return score

study = optuna.create_study(direction = 'maximize')
study.optimize(objective, n_trials = 100, timeout = 60 * 60)
print("Best trial:", study.best_trial.params)

# Best trial: {'lambda_l1': 0.5511594566765063, 'lambda_l2': 7.716533312476801, 'num_leaves': 3}

objective関数内で最大化したいスコアを出力するようにします。
trialが付与されているパラメータが最適化されます。整数値をとるものはsuggest_int、少数を含むものはsuggest_floatで指定しましょう。log=Trueなら対数スケールでサーチしてくれます。

optimizeでサーチを実行します。n_trialsがサーチ回数、timeoutは実行の制限時間です。上記の場合は、60×60=1時間内で最大100回までサーチしてくれます。

最適な値はbest_trial.paramsで取得可能です。

最適化したパラメータで学習

params = {"objective": "regression", "verbose": -1}
params.update(study.best_trial.params)

results = {}
model = lgbm.train(
    params = params,
    train_set = train_ds,
    num_boost_round = 100,
    valid_sets = [train_ds, valid_ds],
    valid_names = ["train", "valid"],
    callbacks = [lgbm.log_evaluation(10), lgbm.record_evaluation(results)]
)
plt.figure(figsize = (12, 4))
plt.plot(results["train"]["l2"])
plt.plot(results["valid"]["l2"])
plt.show()
r2_score(valid_y, model.predict(valid_X))
# 0.5462229337843646

LightGBMに渡すパラメータを更新して再度学習してみましょう。
R2スコアが0.54に上がっていますね。

まとめ

Optunaでパラメータをサーチする方法を紹介しました。
かんたんに精度が上がる手法なので、ぜひ使ってみたいですね。

コメント

タイトルとURLをコピーしました