ハイパーパラメータ最適化
田中VPoE:「モデルのハイパーパラメータ、例えば決定木の深さや学習率は、手動で調整するのは非効率だ。自動的に最適なパラメータを探索する手法がある。」
あなた:「全部の組み合わせを試すんですか?」
田中VPoE:「それが GridSearch だが、パラメータが多いと組み合わせが爆発する。もっと賢い探索方法もあるから、それぞれの特徴を学ぼう。」
GridSearchCV
すべてのパラメータの組み合わせを網羅的に探索します。
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [5, 10, 15],
'min_samples_leaf': [1, 5, 10],
}
# 組み合わせ数: 3 x 3 x 3 = 27通り x 5-fold = 135回の学習
grid_search = GridSearchCV(
RandomForestClassifier(random_state=42),
param_grid,
cv=5,
scoring='f1',
n_jobs=-1,
verbose=1,
)
grid_search.fit(X_train, y_train)
print(f"最適パラメータ: {grid_search.best_params_}")
print(f"最高F1スコア: {grid_search.best_score_:.3f}")
# 結果をDataFrameで確認
results_df = pd.DataFrame(grid_search.cv_results_)
print(results_df[['params', 'mean_test_score', 'std_test_score']]
.sort_values('mean_test_score', ascending=False).head())
GridSearch の長所・短所
| 長所 | 短所 |
|---|---|
| 確実に最適解を見つける | 計算コストが非常に高い |
| 実装が簡単 | パラメータ空間が大きいと非現実的 |
RandomizedSearchCV
パラメータ空間からランダムにサンプリングして探索します。
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import randint, uniform
param_distributions = {
'n_estimators': randint(50, 500),
'max_depth': randint(3, 20),
'min_samples_leaf': randint(1, 20),
'max_features': uniform(0.1, 0.9),
}
random_search = RandomizedSearchCV(
RandomForestClassifier(random_state=42),
param_distributions,
n_iter=50, # 50回サンプリング
cv=5,
scoring='f1',
n_jobs=-1,
random_state=42,
)
random_search.fit(X_train, y_train)
print(f"最適パラメータ: {random_search.best_params_}")
print(f"最高F1スコア: {random_search.best_score_:.3f}")
GridSearch vs RandomizedSearch
| 項目 | GridSearch | RandomizedSearch |
|---|---|---|
| 探索方法 | 網羅的 | ランダム |
| 計算コスト | 高い | 制御可能(n_iter) |
| 最適解の保証 | あり | なし(確率的) |
| パラメータ数が多い場合 | 非現実的 | 効率的 |
Optuna(ベイジアン最適化)
過去の探索結果を活用して、有望なパラメータ領域を効率的に探索します。
import optuna
import lightgbm as lgb
from sklearn.model_selection import cross_val_score
def objective(trial):
params = {
'n_estimators': trial.suggest_int('n_estimators', 50, 500),
'max_depth': trial.suggest_int('max_depth', 3, 15),
'learning_rate': trial.suggest_float('learning_rate', 0.01, 0.3, log=True),
'num_leaves': trial.suggest_int('num_leaves', 10, 100),
'subsample': trial.suggest_float('subsample', 0.5, 1.0),
'colsample_bytree': trial.suggest_float('colsample_bytree', 0.5, 1.0),
'min_child_samples': trial.suggest_int('min_child_samples', 5, 50),
'reg_alpha': trial.suggest_float('reg_alpha', 1e-8, 10.0, log=True),
'reg_lambda': trial.suggest_float('reg_lambda', 1e-8, 10.0, log=True),
}
model = lgb.LGBMClassifier(**params, random_state=42, verbose=-1)
scores = cross_val_score(model, X_train, y_train, cv=5, scoring='f1')
return scores.mean()
# 最適化の実行
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=100, show_progress_bar=True)
print(f"最適パラメータ: {study.best_params}")
print(f"最高F1スコア: {study.best_value:.3f}")
Optuna の特徴
# 最適化の可視化
optuna.visualization.plot_optimization_history(study)
optuna.visualization.plot_param_importances(study)
# パラメータの重要度
importance = optuna.importance.get_param_importances(study)
print("\nパラメータ重要度:")
for param, imp in importance.items():
print(f" {param}: {imp:.3f}")
手法の選択ガイド
| 条件 | 推奨手法 |
|---|---|
| パラメータが2-3個 | GridSearchCV |
| パラメータが4個以上 | RandomizedSearchCV |
| 高精度を追求したい | Optuna |
| 計算リソースが限られる | RandomizedSearchCV(n_iter小) |
| 再現性が最優先 | GridSearchCV |
ハイパーパラメータ最適化の注意点
テストデータでの最適化は厳禁
# 正しい: 学習データ内の交差検証で最適化
grid_search.fit(X_train, y_train) # 学習データのみ
# テストデータでの最終評価は1回だけ
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
final_f1 = f1_score(y_test, y_pred)
print(f"最終テストF1: {final_f1:.3f}")
過剰な最適化への注意
# CV スコアとテストスコアの差が大きい場合、
# ハイパーパラメータが検証データに過学習している可能性がある
print(f"CV最高スコア: {grid_search.best_score_:.3f}")
print(f"テストスコア: {final_f1:.3f}")
gap = grid_search.best_score_ - final_f1
if gap > 0.05:
print("※ ハイパーパラメータの過学習の可能性あり")
まとめ
- GridSearchCV: 網羅的探索、パラメータが少ない場合に有効
- RandomizedSearchCV: ランダム探索、効率的で計算コスト制御可能
- Optuna: ベイジアン最適化、最も効率的な探索
- テストデータでの最適化は厳禁
- ハイパーパラメータ自体の過学習にも注意
チェックリスト
- GridSearchCV の使い方を理解した
- RandomizedSearchCV との違いを説明できる
- Optuna の基本的な使い方を把握した
- ハイパーパラメータ最適化の注意点を理解した
次のステップへ
次は演習です。モデルの評価・改善サイクルを実際に回してみましょう。
推定読了時間: 30分