ベイズ最適化シリーズ5回目。
今回は、リアルな実験でベイズ最適化を使う方法をご紹介します。
ベイズ最適化シリーズ(1) -ベイズ最適化の可視化-
ベイズ最適化シリーズ(2) -アンサンブル学習(Voting)の最適化-
ベイズ最適化シリーズ(3) -XGBoostのハイパーパラメータ探索-
ベイズ最適化シリーズ(4) -ゲームの攻略-
#リアルな実験でベイズ最適化
ベイズ最適化は、機械学習のパラメータ設定のみならず、化学実験や物理実験などのリアルな実験でも威力を発揮します。
今回はGPyOptを使い、リアルな実験を想定したコードを書いてみました。
#実験のながれ
今回想定している実験の流れを下記に示します。
- 予備実験のデータを2つ持っている。(予備実験のデータを持っていない場合でも対応できます。)
- 予備実験のデータをGPyOptに投げ、最初の実験条件を提示してもらう。
- ①提示された条件で実験を行い、実験結果を入力する。
- ②実験結果をGPyOptに投げ、次の実験条件を提示してもらう。
- ①と②を繰り返し、規定回数まで行うと実験終了。
- 最後に、最適な実験条件を提示してもらう。
とりあえず、コードをコピペして動かしていただければ、何をやっているかは分かるかと思います。
#問題設定
本当は、ピタゴラスイッチ的な実験装置を用意したかったのですが、時間の都合上、数値計算で代替しました。
以下のyの最小値を求める問題を考えます。
y = x^2
GPyOptからxが提示されますので、yを計算後、入力するものです。
皆さんが実験する際、上記の式は未知だと思いますので、xを実験条件、yを実験結果に置き換えて使ってみてください。
#コード
import GPy
import GPyOpt
import numpy as np
#予備実験のデータ
initial_x = np.array([-1, 0.5])
initial_y = np.array([1, 0.25])
initial_x = initial_x.reshape((-1,1))
initial_y = initial_y.reshape((-1,1))
#実験回数
exp_num = 5
try_ = 1
def f(x):
global try_
print("Try : " , try_ , " / {0} , next x is ".format(exp_num) , x)
score = float(input("Input y : "))
try_ += 1
return score
bounds = [{'name': 'a', 'type': 'continuous', 'domain': (-2,2)}]#実験条件の範囲
print("Bayesian Optimization")
#予備実験のデータを持っていない場合はinitial_design_numdataの値を変更
myBopt = GPyOpt.methods.BayesianOptimization(f=f,
domain=bounds,
X = initial_x,
Y = initial_y,
initial_design_numdata=0)
myBopt.run_optimization(max_iter=exp_num)
#最適なパラメータ
print("Best x is ",myBopt.x_opt)
ベイズ最適化の際に、渡す変数はこちらを見ていただければ分かります。
#結果
上記のコードを走らせると以下のような結果になります。
なお、Input yの部分は私が手計算して、入力しています。
Bayesian Optimization
Try : 1 / 5 , next x is [[0.60906033]]
Input y : 0.36
Try : 2 / 5 , next x is [[0.21945366]]
Input y : 0.0479
Try : 3 / 5 , next x is [[2.]]
Input y : 4
Try : 4 / 5 , next x is [[-0.087055]]
Input y : 0.0064
Try : 5 / 5 , next x is [[0.01745743]]
Input y : 0.000289
Best x is [0.01745743]
ということで、最適なxは「0.01745」と求められました。
解析的には「0」が最適値ですので、ほぼ到達できたかと思います。
一応、アニメーションにしてみました。
青い点は予備実験のデータで、赤い点はベイズ最適化で実験したものです。