今回は Optuna の便利な使い方について。 現行の Optuna (v0.19.0) には決められた時間内で可能な限り最適化したい、というニーズを満たす API が実装されている。
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.14.6 BuildVersion: 18G1012 $ python -V Python 3.7.5 $ pip list | grep -i optuna optuna 0.19.0
下準備
まずは Optuna と Scikit-learn をインストールしておく。
$ pip install optuna scikit-learn
決められた時間内で最適化するサンプルコード
以下が決められた時間内で可能な限り最適化するサンプルコード。
実現するには Study#optimize()
で n_trials
の代わりに timeout
オプションを指定する。
渡す値は最適化に使う秒数になっており、以下では 60 秒を指定している。
サンプルコードでは、RandomForest で乳がんデータセットを 5-Fold Stratified CV するときのハイパーパラメータを探索している。
#!/usr/bin/env python3 # -*- coding: utf-8 -*- import optuna from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import StratifiedKFold from sklearn.model_selection import cross_validate from sklearn import datasets class Objective: """目的関数に相当するクラス""" def __init__(self, X, y): self.X = X self.y = y def __call__(self, trial): """オブジェクトが呼び出されたときに呼ばれる特殊メソッド""" # RandomForest のパラメータを最適化してみる params = { 'n_estimators': 100, 'max_depth': trial.suggest_int('max_depth', 2, 32), 'min_samples_leaf': trial.suggest_int('min_samples_leaf', 1, 16), } model = RandomForestClassifier(**params) # 5-Fold Stratified CV kf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42) scores = cross_validate(model, X=self.X, y=self.y, cv=kf, # メトリックは符号を反転したロジスティック損失 scoring='neg_log_loss', n_jobs=-1) return scores['test_score'].mean() def main(): dataset = datasets.load_breast_cancer() X, y = dataset.data, dataset.target objective = Objective(X, y) # 関数を最大化するように最適化する study = optuna.create_study(direction='maximize') # 試行回数ではなく特定の時間内で最適化する study.optimize(objective, timeout=60) # この例では 60 秒 print('params:', study.best_params) if __name__ == '__main__': main()
実行すると、次のようになる。
$ python optimeout.py [I 2019-12-02 18:45:41,029] Finished trial#0 resulted in value: -0.1420495901047513. Current best value is -0.1420495901047513 with parameters: {'max_depth': 28, 'min_samples_leaf': 9}. ... [I 2019-12-02 18:46:39,488] Finished trial#25 resulted in value: -0.11825965818535904. Current best value is -0.11397258384370261 with parameters: {'max_depth': 6, 'min_samples_leaf': 1}. params: {'max_depth': 6, 'min_samples_leaf': 1}
上記を見ると、約 1 分で最適化が終了していることがわかる。
ぶっちゃけやってみるまで 1 回の試行にどれだけ時間がかかるかなんてわからないし、試行回数を指定するより便利だと思う。
- 作者: 門脇大輔,阪田隆司,保坂桂佑,平松雄司
- 出版社/メーカー: 技術評論社
- 発売日: 2019/10/09
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
スマートPythonプログラミング: Pythonのより良い書き方を学ぶ
- 作者: もみじあめ
- 発売日: 2016/03/12
- メディア: Kindle版
- この商品を含むブログ (1件) を見る