Bamba news

ベイズ最適化を実装してみよう!わかりやすく解説

【スマホからでも実行可能】ベイズ最適化の実装方法をPythonコード付きで徹底解説。機械学習のハイパーパラメータチューニングを効率化したい方必見。サンプルコードを動かしながら、実践的に学べます。


はじめに

ベイズ最適化の入門編、活用例編に続き、この実践編では、実際にPythonを使ってベイズ最適化を動かしていきます。これまでの記事で概念や活用イメージを掴んだ方も、「実際にどうやって使うの?」という疑問をお持ちかもしれません。

この記事では、難しい理論は一旦横に置き、コードを書きながら「手を動かして理解する」ことを目指します。具体的なサンプルコードを通して、ベイズ最適化がどのように問題を解決してくれるのかを体感していきましょう。機械学習のモデルチューニングなど、現実の課題に応用するための第一歩です。

記事の最後に、環境構築なしでスマホからでも即実行可能なGoogle Colabノートブックをご用意しています。ぜひ、ご自身の環境でコードを動かしながら読み進めてみてください。


ベイズ最適化の仕組み(簡単なおさらい)

実装に入る前に、ベイズ最適化が何をしてくれるのかを簡単におさらいしましょう。

ベイズ最適化は、「中身がよくわからない関数(ブラックボックス関数)」の出力が最大(または最小)になるような入力値を見つけ出すための賢い手法です。

例えば、新しいコーヒー豆の焙煎時間と温度を調整して、最も美味しくなる組み合わせを探す問題を考えてみてください。毎回、すべての組み合わせを試すのは時間もコストもかかります。

ベイズ最適化は、この試行錯誤を効率化するために、2つの重要な要素を使います。

  1. 代理モデル(Surrogate Model): これまで試した「入力(焙煎時間・温度)」と「結果(美味しさの点数)」のデータから、関数全体の「おおよその形」を予測します。「このあたりは点数が高そうだ」「あちらはまだ試していないからどうなるか分からない」といった、全体の傾向を把握するモデルです。
  2. 獲得関数(Acquisition Function): 代理モデルの予測結果をもとに、「次にどこを試すべきか」を決定します。「既に点数が高いと予測されている場所をさらに探求(Exploitation)するか」、それとも「まだデータがなくてよく分からないけど、もしかしたらすごく良い結果が出るかもしれない未知の場所を探索(Exploration)するか」のバランスを取りながら、最も効率的に良い結果を見つけられる可能性が高い場所を教えてくれます。

この「予測」と「次の一手の決定」を繰り返すことで、最小限の試行回数で最適な答えにたどり着くことができるのです。


実装の準備:ライブラリのインストール

それでは、実際にPythonでベイズ最適化を実装していきましょう。今回は、そのものずばりbayesian-optimizationという、非常に使いやすいライブラリを利用します。

まずは、このライブラリをインストールします。ターミナルやコマンドプロンプトで以下のコマンドを実行してください。

pip install bayesian-optimization

機械学習の応用例ではscikit-learnも使用しますので、こちらもインストールしておくとスムーズです。

pip install scikit-learn numpy

これで準備は完了です。


1. 基本的な関数の最適化

最初に、シンプルな数学的な関数を対象に、ベイズ最適化がどのように最大値を見つけるのかを見ていきましょう。

STEP 1: 最適化したい関数(ブラックボックス関数)の定義

まず、私たちが最大値を探したい「ブラックボックス関数」を定義します。ここでは、中身の式は私たちが知っていますが、ベイズ最適化アルゴリズムはこれを知らない、という想定で進めます。

例として、少し複雑な形の関数を用意しました。この関数のグラフをパッと見て最大値がどこかを当てるのは難しいでしょう。

import numpy as np

# 最適化の対象とするブラックボックス関数
def black_box_function(x):
  """
  入力xに対して、ある値を返す関数。
  この関数の最大値を探したい。
  """
  return np.exp(-(x - 2)**2) + np.exp(-(x - 6)**2 / 10) + 1 / (x**2 + 1)

STEP 2: ベイズ最適化の実行

次に関数を最適化します。bayesian-optimizationライブラリのBayesianOptimizationクラスを使います。

やることは主に以下の3つです。

  1. 最適化オブジェクトの作成:
    • f: 最適化したい関数(先ほど定義したblack_box_function)を渡します。
    • pbounds: パラメータxの探索範囲(pはparameter、boundsは範囲の意味)を指定します。今回は-2から10の範囲で探すことにします。
  2. 最適化の実行:
    • .maximize()メソッドを呼び出します。
    • init_points: 最初にランダムに試す回数を指定します。これにより、ある程度関数の全体像を把握します。
    • n_iter: 獲得関数を使って賢く探索する回数を指定します。

それでは、コードを見てみましょう。

from bayes_opt import BayesianOptimization

# 1. 探索範囲の定義
# パラメータ'x'を-2から10の範囲で探索する
pbounds = {'x': (-2, 10)}

# 2. ベイズ最適化オブジェクトの生成
optimizer = BayesianOptimization(
    f=black_box_function,  # 最適化する関数
    pbounds=pbounds,       # 探索範囲
    random_state=1,        # 結果を固定するためのシード値
    verbose=2              # 途中経過の表示(2:詳細, 1:簡潔, 0:非表示)
)

# 3. 最適化の実行
# init_points: 初期探索の回数
# n_iter: ベイズ最適化による探索の回数
optimizer.maximize(
    init_points=2,
    n_iter=10
)

これを実行すると、探索の過程が1ステップずつ表示されます。targetが関数の出力値です。回数を重ねるごとに、より高いtargetの値を見つけようとしていることがわかります。

STEP 3: 結果の確認

最適化が完了したら、見つかった最も良い結果を確認します。optimizer.maxプロパティに、最も良かった時のパラメータと、その時の関数の値が格納されています。

# 最適化結果の表示
print("見つかった最大値と、その時のxの値:")
print(optimizer.max)

この簡単な例を通して、ベイズ最適化が指定された範囲内で関数の最大値を見つけ出すプロセスを体験できました。


2. 機械学習モデルへの応用(ハイパーパラメータチューニング)

ベイズ最適化が最も活躍する場面の一つが、機械学習モデルのハイパーパラメータチューニングです。

モデルの性能は、「学習率」や「木の深さ」といったハイパーパラメータによって大きく変わります。これらの最適な組み合わせを見つける作業は、まさに「ブラックボックス関数の最適化」問題そのものです。

ここでは、人気の高い機械学習アルゴリズムであるXGBoostを例に、ベイズ最適化で最適なハイパーパラメータを探してみましょう。

STEP 1: 評価関数の定義

まず、最適化の対象となる「評価関数」を定義します。この関数は、ハイパーパラメータの組み合わせを受け取り、モデルの性能スコア(今回は交差検証の平均スコア)を返すものです。このスコアを最大化することが目標になります。

注意: XGBoostのハイパーパラメータには整数型(max_depthなど)を指定する必要があるものがあります。bayesian-optimizationライブラリは浮動小数点数でパラメータを探索するため、関数内で整数に変換する処理を入れる必要があります。

from sklearn.model_selection import cross_val_score
from sklearn.datasets import make_classification
from xgboost import XGBClassifier

# データセットの生成(サンプル)
X, y = make_classification(
    n_samples=1000,
    n_features=10,
    n_informative=5,
    n_redundant=5,
    random_state=1
)

# ベイズ最適化で評価するための関数を定義
def xgb_evaluate(max_depth, learning_rate, n_estimators, gamma):
    """
    XGBoostのハイパーパラメータを受け取り、
    交差検証による評価スコアを返す関数
    """
    # パラメータの型を整数に変換
    max_depth = int(max_depth)
    n_estimators = int(n_estimators)

    # モデルの定義
    model = XGBClassifier(
        max_depth=max_depth,
        learning_rate=learning_rate,
        n_estimators=n_estimators,
        gamma=gamma,
        random_state=1,
        eval_metric='logloss'
    )

    # 交差検証でスコアを計算
    # cv=3 は3分割交差検証を意味する
    scores = cross_val_score(model, X, y, cv=3, scoring='accuracy')

    # スコアの平均値を返す
    return scores.mean()

STEP 2: 探索範囲の定義と最適化の実行

次に、チューニングしたい各ハイパーパラメータの探索範囲を定義し、先ほどと同じように最適化を実行します。今回は4つのパラメータを同時に探索します。

# 探索したいハイパーパラメータの範囲を定義
pbounds = {
    'max_depth': (3, 10),           # 木の深さ (3から10の間)
    'learning_rate': (0.01, 0.3),   # 学習率 (0.01から0.3の間)
    'n_estimators': (100, 1000),    # 決定木の数 (100から1000の間)
    'gamma': (0, 5),                # 損失減少の閾値 (0から5の間)
}

# ベイズ最適化オブジェクトの生成
xgb_optimizer = BayesianOptimization(
    f=xgb_evaluate,
    pbounds=pbounds,
    random_state=1,
    verbose=2
)

# 最適化の実行
# ここでは初期5回、探索15回の計20回試行します
xgb_optimizer.maximize(
    init_points=5,
    n_iter=15
)

実行すると、様々なハイパーパラメータの組み合わせでモデルの学習と評価が繰り返され、徐々に精度の高い組み合わせが見つかっていく様子が確認できます。

STEP 3: 最良のハイパーパラメータの確認

最後に、見つかった最も性能の良かったハイパーパラメータの組み合わせを確認しましょう。

# 最も良かったハイパーパラメータの組み合わせを表示
print("最適なハイパーパラメータ:")
print(xgb_optimizer.max)

このように、手作業や当てずっぽう(ランダムサーチ)、あるいは全ての組み合わせを試す(グリッドサーチ)よりもはるかに効率的に、高い性能を発揮するハイパーパラメータの組み合わせを見つけ出すことができました。


まとめ

今回は、ベイズ最適化の実践編として、Pythonのライブラリを使って実際に問題を解く手順を解説しました。

  • 基本的な関数の最大値探索を通して、ベイズ最適化の基本的な動きを確認しました。
  • 機械学習モデルのハイパーパラメータチューニングという、より実践的な応用例を通して、その強力さと有用性を体感しました。

ベイズ最適化は、試行錯誤にコストがかかる様々な問題に応用できる、非常に強力なツールです。製品の設計、化学実験の条件設定、アルゴリズムのパラメータ調整など、活用の幅は無限大です。

この記事が、皆さんがベイズ最適化を自身の課題解決に役立てるための一助となれば幸いです。


ゲームで学ぶ探索アルゴリズム実践入門~木探索とメタヒューリスティクス

探索技術とそれを支えるアルゴリズムにフォーカスを当て、ゲームAIを題材にその重要性と魅力を楽しく学ぶための入門書です。

▶ Amazonで見る

環境構築なし
実行できるファイルはこちら!

このボタンからGoogle Colabを開き、すぐにコードをお試しいただけます。

関連する記事

ガウス過程回帰を実装してみよう!わかりやすく解説

【スマホからでも実行可能】Pythonでガウス過程回帰を実装する方法を初心者向けにわかりやすく解説します。機械学習のモデル構築や不確実性の可視化に興味がある方必見です。

エクストラツリー(ExtraTrees)を実装してみよう!わかりやすく解説

【スマホからでも実行可能】この記事では、機械学習のアルゴリズムであるエクストラツリー(ExtraTrees)について、その仕組みからPythonによる実装方法までを丁寧に解説します。ランダムフォレストとの違いも理解しながら、実践的なスキルを身につけましょう。

勾配ブースティング木(Gradient Boosted Trees)を実装してみよう!わかりやすく解説

【スマホからでも実行可能】勾配ブースティング木は、機械学習の分野で非常に強力な予測モデルの一つです。この記事では、その仕組みとPythonによる具体的な実装方法を、初心者にも分かりやすく解説します。実際にコードを動かしながら、この強力なアルゴリズムを体験してみましょう。

ランダムフォレストを実装してみよう!わかりやすく解説

【スマホからでも実行可能】ランダムフォレストの実装方法をPythonコード付きで丁寧に解説。機械学習のアンサンブル学習を実際に動かして理解を深めましょう。初心者にもわかりやすい実践ガイドです。

決定木(Decision Tree)を実装してみよう!わかりやすく解説

【スマホからでも実行可能】決定木の実装方法をPythonコード付きでステップバイステップ解説。データの準備からモデル構築、可視化、評価、チューニングまで、実践的なスキルが身につきます。機械学習の基本である決定木をマスターしましょう。