ハイパーパラメータチューニングは、モデルの学習率・木の深さ・正則化係数といった「学習では決まらないパラメータ」を最適化する工程です。 Databricksでは主にHyperopt(SparkTrialsによる分散探索)とOptunaが使われ、全トライアルをMLflow Trackingで自動記録できます。 ML Associate試験ではHyperoptの基本API、ML Professional試験ではSparkTrials vs Trialsの使い分けが頻出です。
ハイパーパラメータの探索空間から最適な組み合わせを見つけるためのアルゴリズムは、大きく3種類に分かれます。
| 戦略 | 仕組み | 長所 | 短所 | 代表ツール |
|---|---|---|---|---|
| Grid Search | 指定した全組み合わせを網羅的に試行 | 再現性が高い。パラメータ数が少ない場合に有効 | 探索空間が指数的に増加(次元の呪い) | scikit-learn GridSearchCV |
| Random Search | 探索空間からランダムにサンプリング | Grid Searchより少ない試行で良い解を発見しやすい | 重要でないパラメータにも均等にリソースを割く | scikit-learn RandomizedSearchCV |
| Bayesian Optimization | 過去の試行結果から確率モデル(TPE等)を構築し、次に試すべき点を予測 | 少ない試行で最適解に収束。高次元空間に強い | 逐次依存性があり純粋な並列化に工夫が必要 | Hyperopt (TPE), Optuna (TPE) |
Databricksの実務・試験の両方で最も重要なのはBayesian Optimization(TPE: Tree-structured Parzen Estimator)です。 HyperoptもOptunaもデフォルトでTPEを採用しており、50〜200回程度のトライアルで高次元空間でも良好な解を見つけられます。
HyperoptはDatabricksに組み込まれているベイズ最適化ライブラリです。fmin()関数に目的関数・探索空間・アルゴリズム・最大試行数を渡すだけでチューニングが実行されます。
| 関数 | 用途 | 例 |
|---|---|---|
hp.choice(label, options) | カテゴリカル値(離散選択) | hp.choice("algo", ["rf", "xgb", "lgb"]) |
hp.uniform(label, low, high) | 一様分布(連続値) | hp.uniform("dropout", 0.1, 0.5) |
hp.loguniform(label, low, high) | 対数一様分布(学習率など桁が変わるパラメータ) | hp.loguniform("lr", log(1e-5), log(1e-1)) |
hp.quniform(label, low, high, q) | 量子化一様分布(整数パラメータ) | hp.quniform("max_depth", 3, 15, 1) |
from hyperopt import fmin, tpe, hp, STATUS_OK, SparkTrials
import mlflow
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
# 探索空間の定義
search_space = {
"n_estimators": hp.quniform("n_estimators", 50, 500, 50),
"max_depth": hp.quniform("max_depth", 3, 15, 1),
"min_samples_split": hp.quniform("min_samples_split", 2, 20, 1),
"learning_rate": hp.loguniform("learning_rate", np.log(1e-4), np.log(1e-1)),
}
# 目的関数(最小化対象を返す)
def objective(params):
params["n_estimators"] = int(params["n_estimators"])
params["max_depth"] = int(params["max_depth"])
params["min_samples_split"] = int(params["min_samples_split"])
clf = RandomForestClassifier(**params, random_state=42)
score = cross_val_score(clf, X_train, y_train, cv=3, scoring="f1").mean()
# MLflowにメトリクスを記録
mlflow.log_metrics({"f1_cv": score})
# STATUS_OKとlossを返す(lossは最小化される)
return {"loss": -score, "status": STATUS_OK}
# SparkTrialsで分散実行
spark_trials = SparkTrials(parallelism=8)
with mlflow.start_run(run_name="hyperopt_rf_tuning"):
best_params = fmin(
fn=objective,
space=search_space,
algo=tpe.suggest, # TPE(Bayesian Optimization)
max_evals=100, # 最大100トライアル
trials=spark_trials, # Spark Executorで並列実行
)目的関数は必ず {"loss": 値, "status": STATUS_OK} の形式で辞書を返します。lossはfminが最小化する値なので、精度を最大化したい場合は負の値(-score)を返します。
Hyperoptの実行モードを決めるのがTrialsクラスの選択です。クラスタリソースを活用するかどうかで大きく性能が変わります。
| 項目 | Trials | SparkTrials |
|---|---|---|
| 実行場所 | ドライバーノード(単一マシン) | Spark Executor(クラスタ全体) |
| 並列度 | 逐次実行のみ | parallelismパラメータで並列数を指定 |
| 適したモデル | scikit-learn等の単一マシンML | scikit-learn等の単一マシンML(各Executorで独立実行) |
| MLflow連携 | 手動でログ記録が必要 | 各トライアルをネストされたRunとして自動記録 |
| 推奨parallelism | — | クラスタのワーカー数と同じか、max_evalsの平方根 |
| 注意点 | 100トライアルでもドライバー1台で逐次処理 | parallelismが高すぎるとTPEの逐次最適化の利点が減る |
SparkTrialsのparallelismにはトレードオフがあります。 値を大きくすると物理的な並列度は上がりますが、TPEは過去の結果を使って次の探索点を決めるため、 並列度が高すぎると「まだ結果が返っていないトライアルが多い状態」で次の点を選ぶことになり、ランダム探索に近づきます。 実務では max_evals の平方根程度が推奨されています。
Optunaは日本のPreferred Networks社が開発したベイズ最適化フレームワークです。Hyperoptとは異なり、Pruning(早期打ち切り)を標準サポートしており、無駄なトライアルを途中で打ち切ることで計算コストを削減できます。
| API | 役割 |
|---|---|
optuna.create_study(direction) | 最適化スタディの作成("minimize" or "maximize") |
study.optimize(objective, n_trials) | 指定回数の最適化を実行 |
trial.suggest_int(name, low, high) | 整数パラメータの探索 |
trial.suggest_float(name, low, high, log) | 浮動小数点パラメータの探索(log=Trueで対数スケール) |
trial.suggest_categorical(name, choices) | カテゴリカル値の探索 |
trial.report(value, step) | 中間結果の報告(Pruning判定に使用) |
trial.should_prune() | Pruning判定(Trueなら早期終了) |
import optuna
import mlflow
from sklearn.ensemble import GradientBoostingClassifier
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", 1e-4, 1e-1, log=True),
"subsample": trial.suggest_float("subsample", 0.5, 1.0),
"min_samples_split": trial.suggest_int("min_samples_split", 2, 20),
}
clf = GradientBoostingClassifier(**params, random_state=42)
score = cross_val_score(clf, X_train, y_train, cv=3, scoring="f1").mean()
# MLflowにトライアル結果を記録
with mlflow.start_run(nested=True):
mlflow.log_params(params)
mlflow.log_metric("f1_cv", score)
return score
with mlflow.start_run(run_name="optuna_gbm_tuning"):
study = optuna.create_study(direction="maximize")
study.optimize(objective, n_trials=100)
# 最良パラメータの記録
mlflow.log_params(study.best_params)
mlflow.log_metric("best_f1", study.best_value)| 項目 | Hyperopt | Optuna |
|---|---|---|
| 探索アルゴリズム | TPE、Random Search、Adaptive TPE | TPE、CMA-ES、Random Search、Grid Search、GP |
| Databricks分散対応 | SparkTrialsでネイティブ対応 | Joblib等で並列化可能だがSpark統合はなし |
| Pruning(早期打ち切り) | 標準サポートなし | MedianPruner / HyperbandPruner等を標準装備 |
| 目的関数の返り値 | loss(最小化)+ STATUS_OKの辞書 | スカラー値(direction指定で最大/最小化を選択) |
| MLflow連携 | SparkTrials使用時に自動記録 | 手動でmlflow.start_run(nested=True) |
| AutoMLとの関係 | Databricks AutoMLの内部エンジン | AutoMLでは使用されない |
| 可視化 | MLflow UIを利用 | optuna.visualizationで探索過程を可視化 |
| 試験での重要度 | ML Associate / ML Professional で頻出 | 直接の出題は少ないが概念理解に有用 |
Databricks AutoMLは、データを渡すだけで前処理・特徴量エンジニアリング・モデル選択・ハイパーパラメータチューニングを自動実行する機能です。内部でHyperoptのTPEアルゴリズムを使って各モデルのハイパーパラメータを探索し、全トライアルをMLflow Experimentに自動記録します。
Hyperopt + SparkTrialsを使用すると、各トライアルは親Runの下にネストされた子Runとして自動記録されます。これにより、MLflow UIで全トライアルのパラメータ・メトリクスを一覧比較できます。
| 試験 | 出題範囲 | 重要ポイント |
|---|---|---|
| ML Associate | Hyperoptの基本 | fmin / hp.choice / hp.loguniform / STATUS_OKの意味と使い方 |
| ML Associate | 探索戦略の違い | Grid Search vs Random Search vs Bayesian Optimizationの特徴 |
| ML Professional | SparkTrials vs Trials | 分散実行と単一マシン実行の違い、parallelismの設定 |
| ML Professional | MLflow連携 | SparkTrials使用時の自動ネストRun記録、結果の比較 |
| ML Professional | AutoMLとの関係 | AutoMLが内部でHyperoptを使用している事実、生成Notebookの活用 |
ML Professional
問題 1
MLエンジニアが8ワーカーのDatabricksクラスタ上で、scikit-learnのランダムフォレストに対して100パターンのハイパーパラメータチューニングを実行したい。クラスタリソースを最大限活用しつつ、TPEの探索効率も維持する方法として最も適切なのはどれか。
正解: B
SparkTrialsを使えばSpark Executorにトライアルを分散できます。parallelism=8はワーカー数と一致し、max_evals(100)の平方根(≈10)にも近いため合理的です。選択肢Aはクラスタリソースを活用しません。選択肢Cはparallelism=100でTPEの「過去の結果を活用して次の点を選ぶ」利点がほぼ失われ、ランダム探索と同等になります。選択肢DのOptunaはDatabricksのSparkTrials統合を持たず、最適な方法ではありません。
HyperoptとOptunaはどちらを使うべきですか?
Databricksエコシステムとの統合を重視するならHyperoptが第一選択です。SparkTrialsによるクラスタ全体での分散チューニング、AutoMLの内部エンジンとしての採用、MLflow Trackingとの自動連携が強みです。一方、Pruning(早期打ち切り)による効率化やTPE以外の探索アルゴリズム(CMA-ES等)が必要な場合、または他クラウドやオンプレミスでも同一コードを使いたい場合はOptunaが適しています。試験対策ではHyperoptが優先です。
SparkTrialsとTrialsの違いは何ですか?
Trialsは単一マシン上で逐次的にトライアルを実行するクラスで、ドライバーノード1台のリソースしか使いません。SparkTrialsはSpark Executorにトライアルを分散し、クラスタ全体で並列実行します。たとえば8ワーカーのクラスタなら最大8トライアルを同時実行でき、100トライアルの実行時間を大幅に短縮できます。ML Professional試験ではこの違いが頻出です。
ハイパーパラメータチューニングとAutoMLの関係は?
Databricks AutoMLは内部でHyperoptを使用してハイパーパラメータ探索を行います。AutoMLは前処理・特徴量エンジニアリング・モデル選択・チューニングを自動化する上位レイヤーで、各トライアルはMLflowに自動記録されます。AutoMLが生成したNotebookにはHyperoptのコードが含まれており、それをカスタマイズして独自のチューニングパイプラインを構築することも可能です。
NicheeLab編集部
データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。
Databricks資格一覧|全7試験・難易度・勉強法
Databricks認定資格全7試験の一覧・難易度・出題範囲・合格ラインを徹底解説。2026年最新版の公式試験ガイドに準...
Databricks試験の難易度ランキング|全7資格を徹底比較
Databricks認定全7試験の難易度をランキング形式で徹底比較。合格率・学習時間・出題傾向から難易度を分析。...
Databricks資格の勉強方法|最短合格ルートと学習時間の目安
Databricks認定資格に最短で合格するための勉強方法を完全ガイド。公式リソース・問題集・学習スケジュールを徹底解説...
Databricks Data Engineer Associate完全解説|出題範囲・問題例・合格戦略
Databricks Certified Data Engineer Associate試験を徹底解説。5つの出題ドメイ...
Databricks Data Engineer Professional完全解説|上級試験の攻略法
Databricks Certified Data Engineer Professional試験を徹底解説。10の出題...