まとめ- Optuna はベイズ最適化(TPE: Tree-structured Parzen Estimator)を用いて効率的にハイパーパラメータを探索する。
- 枝刈り(Pruning)で有望でない試行を早期に打ち切り、計算コストを大幅に削減する。
optuna.visualization でパラメータの重要度や探索履歴を直感的に可視化できる。
- 交差検証 — Optuna の目的関数内で CV を使うことが一般的です
- 検証曲線 — 手動チューニングとの対比
直感
#
GridSearch は指定した組み合わせを全探索するが、10個のパラメータ×5段階で約1000万通り。Optuna は過去の試行結果から「次に試すべき有望な領域」を推定し、少ない回数で良いパラメータに到達する。イメージは「宝探しで、掘るたびに地図が更新される」手法。
詳細な解説
#
ライブラリとデータ
#
1
2
3
4
5
6
7
| import optuna
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score
from sklearn.ensemble import GradientBoostingClassifier
optuna.logging.set_verbosity(optuna.logging.WARNING)
X, y = load_breast_cancer(return_X_y=True)
|
目的関数の定義
#
1
2
3
4
5
6
7
8
9
10
11
| def objective(trial):
params = {
"n_estimators": trial.suggest_int("n_estimators", 50, 300),
"max_depth": trial.suggest_int("max_depth", 2, 8),
"learning_rate": trial.suggest_float("learning_rate", 0.01, 0.3, log=True),
"subsample": trial.suggest_float("subsample", 0.5, 1.0),
"min_samples_split": trial.suggest_int("min_samples_split", 2, 20),
}
model = GradientBoostingClassifier(**params, random_state=42)
score = cross_val_score(model, X, y, cv=5, scoring="roc_auc")
return score.mean()
|
最適化の実行
#
1
2
3
4
5
| study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=50, show_progress_bar=True)
print(f"Best AUC: {study.best_value:.4f}")
print(f"Best params: {study.best_params}")
|
結果の可視化
#
1
2
3
4
5
6
7
8
| # パラメータの重要度
optuna.visualization.plot_param_importances(study).show()
# 最適化の履歴
optuna.visualization.plot_optimization_history(study).show()
# パラメータ間の関係
optuna.visualization.plot_contour(study, params=["learning_rate", "max_depth"]).show()
|
GridSearch / RandomSearch との比較
#
| 手法 | 探索戦略 | 計算効率 | 枝刈り | 動的な探索空間 |
|---|
| GridSearch | 格子探索 | 低(組合せ爆発) | ✗ | ✗ |
| RandomSearch | ランダム | 中 | ✗ | ✗ |
| Optuna (TPE) | ベイズ最適化 | 高 | ✓ | ✓ |