LESSON

ハイパーパラメータ最適化

田中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

項目GridSearchRandomizedSearch
探索方法網羅的ランダム
計算コスト高い制御可能(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分