この jupyter notebook ファイルは ISSP Data Repository (develop branch) から入手できます。
多目的最適化
\(y \prec y^{'}\Longleftrightarrow \forall \ i \le p, y_i \le y^{'}_i \land \exists \ j \le p, y_j < y^{'}_j\)
PHYSBOでは、パレート解を効率的に求めるためのベイズ最適化手法を実装しています。
[1]:
import time
import numpy as np
import matplotlib.pyplot as plt
import physbo
%matplotlib inline
seed = 12345
num_random_search = 10
num_bayes_search = 40
テスト関数
\(y_1\) と \(y_2\) はそれぞれ \(x_1 = x_2 = \cdots x_N = 1/\sqrt{N}\) と \(x_1 = x_2 = \cdots x_N = -1/\sqrt{N}\) に最小値があり、その値はともに0です。また、上界は1 です。
PHYSBO は最大化問題を仮定するため、-1を掛けたものをあらためて目的関数とします。
参考文献
Van Veldhuizen, David A. Multiobjective evolutionary algorithms: classifications, analyses, and new innovations. No. AFIT/DS/ENG/99-01. AIR FORCE INST OF TECH WRIGHT-PATTERSONAFB OH SCHOOL OF ENGINEERING, 1999.
[2]:
def vlmop2_minus(x):
n = x.shape[1]
y1 = 1 - np.exp(-1 * np.sum((x - 1/np.sqrt(n)) ** 2, axis = 1))
y2 = 1 - np.exp(-1 * np.sum((x + 1/np.sqrt(n)) ** 2, axis = 1))
return np.c_[-y1, -y2]
探索候補データの準備
入力空間 \(\vec{x}\) は 2次元とし、[-2, 2] × [-2, 2] の上で候補点をグリッド状に生成します。
[3]:
min_X = np.array([-2.0, -2.0])
max_X = np.array([2.0, 2.0])
test_X = physbo.search.utility.make_grid(min_X=min_X, max_X=max_X, num_X=101)
[4]:
test_X
[4]:
array([[-2. , -2. ],
[-2. , -1.96],
[-2. , -1.92],
...,
[ 2. , 1.92],
[ 2. , 1.96],
[ 2. , 2. ]], shape=(10201, 2))
[5]:
test_X.shape
[5]:
(10201, 2)
simulator の定義
[6]:
simu = physbo.search.utility.Simulator(test_X, vlmop2_minus)
関数のプロット
1つ目の目的関数
[7]:
t_all = vlmop2_minus(test_X)
plt.figure()
plt.imshow(t_all[:,0].reshape((101,101)), vmin=-1.0, vmax=0.0, origin="lower", extent=[-2.0, 2.0, -2.0, 2.0])
plt.title("objective 1")
plt.colorbar()
plt.plot([1.0/np.sqrt(2.0)], [1.0/np.sqrt(2.0)], '*')
plt.show()
2つ目の目的関数
[8]:
# plot objective 2
plt.figure()
plt.imshow(t_all[:,1].reshape((101,101)), vmin=-1.0, vmax=0.0, origin="lower", extent=[-2.0, 2.0, -2.0, 2.0])
plt.title("objective 2")
plt.colorbar()
plt.plot([-1.0/np.sqrt(2.0)], [-1.0/np.sqrt(2.0)], '*')
plt.show()
最適化の実行
Policy のセット
physbo.search.discrete_multi.Policy を利用します。num_objectives に目的関数の数を指定してください。[9]:
policy = physbo.search.discrete_multi.Policy(test_X=test_X, num_objectives=2)
policy.set_seed(seed)
physbo.search.discrete.policy (目的関数が1つの場合)と同じく、random_search または bayes_search メソッドを呼ぶことで最適化を行います。discrete.policy とおおよそ共通しています。ランダムサーチ
今回のチュートリアルでは、10 (num_random_search) 回のランダムサンプリングと40 (num_bayes_search) 回のベイズ最適化を行います。 比較のために、50 (num_random_search + num_bayes_search) 回のランダムサンプリングも行っておきます。
[10]:
policy = physbo.search.discrete_multi.Policy(test_X=test_X, num_objectives=2)
policy.set_seed(seed)
res_random = policy.random_search(max_num_probes=num_random_search + num_bayes_search, simulator=simu, is_disp=True)
0001-th step: f(x) = [-0.99017418 -0.09267839] (action = 2560)
Pareto set updated.
the number of Pareto frontiers = 1
0002-th step: f(x) = [-0.63368874 -0.93288369] (action = 4415)
Pareto set updated.
the number of Pareto frontiers = 2
0003-th step: f(x) = [-0.89500547 -0.99942328] (action = 10046)
0004-th step: f(x) = [-0.52496048 -0.73019147] (action = 5205)
Pareto set updated.
the number of Pareto frontiers = 2
0005-th step: f(x) = [-0.06210869 -0.9918999 ] (action = 7542)
Pareto set updated.
the number of Pareto frontiers = 3
0006-th step: f(x) = [-0.78149934 -0.9714881 ] (action = 4018)
0007-th step: f(x) = [-0.99988434 -0.7158834 ] (action = 2631)
0008-th step: f(x) = [-0.46814364 -0.99957312] (action = 8063)
0009-th step: f(x) = [-0.58802709 -0.95199271] (action = 7519)
0010-th step: f(x) = [-0.64563383 -0.99949924] (action = 9458)
0011-th step: f(x) = [-0.85901111 -0.77832121] (action = 3396)
0012-th step: f(x) = [-0.6258165 -0.91403294] (action = 4413)
0013-th step: f(x) = [-0.96339156 -0.50605126] (action = 2577)
Pareto set updated.
the number of Pareto frontiers = 4
0014-th step: f(x) = [-0.99433124 -0.07837382] (action = 2955)
Pareto set updated.
the number of Pareto frontiers = 5
0015-th step: f(x) = [-0.77709331 -0.99991896] (action = 7370)
0016-th step: f(x) = [-0.44837296 -0.80073444] (action = 5909)
Pareto set updated.
the number of Pareto frontiers = 6
0017-th step: f(x) = [-0.86544619 -0.41433595] (action = 3787)
Pareto set updated.
the number of Pareto frontiers = 6
0018-th step: f(x) = [-0.56161131 -0.97933576] (action = 8027)
0019-th step: f(x) = [-0.99973799 -0.54162892] (action = 2034)
0020-th step: f(x) = [-0.99984173 -0.61123124] (action = 1231)
0021-th step: f(x) = [-0.97820847 -0.8330008 ] (action = 6382)
0022-th step: f(x) = [-0.99526434 -0.9637083 ] (action = 7282)
0023-th step: f(x) = [-0.97787893 -0.26212082] (action = 2569)
Pareto set updated.
the number of Pareto frontiers = 7
0024-th step: f(x) = [-0.24330703 -0.9118224 ] (action = 5619)
Pareto set updated.
the number of Pareto frontiers = 8
0025-th step: f(x) = [-0.24153475 -0.99178622] (action = 8040)
Pareto set updated.
the number of Pareto frontiers = 9
0026-th step: f(x) = [-0.84190968 -0.91981439] (action = 3506)
0027-th step: f(x) = [-0.99796446 -0.34753927] (action = 3349)
0028-th step: f(x) = [-0.99708276 -0.9919242 ] (action = 8291)
0029-th step: f(x) = [-0.99920018 -0.98099933] (action = 172)
0030-th step: f(x) = [-0.99665356 -0.14456179] (action = 2751)
0031-th step: f(x) = [-0.81366367 -0.99993226] (action = 7170)
0032-th step: f(x) = [-0.54951231 -0.9993634 ] (action = 9158)
0033-th step: f(x) = [-0.19615996 -0.94679724] (action = 6924)
Pareto set updated.
the number of Pareto frontiers = 9
0034-th step: f(x) = [-0.99950572 -0.99575833] (action = 81)
0035-th step: f(x) = [-0.79425482 -0.43043543] (action = 4491)
Pareto set updated.
the number of Pareto frontiers = 10
0036-th step: f(x) = [-0.94523115 -0.58027949] (action = 2782)
0037-th step: f(x) = [-0.9930067 -0.93998722] (action = 6981)
0038-th step: f(x) = [-0.99560251 -0.10351929] (action = 2653)
0039-th step: f(x) = [-0.97602834 -0.99134066] (action = 2409)
0040-th step: f(x) = [-0.05507465 -0.95545924] (action = 6527)
Pareto set updated.
the number of Pareto frontiers = 10
0041-th step: f(x) = [-0.54838423 -0.96652902] (action = 7723)
0042-th step: f(x) = [-0.97560369 -0.9981919 ] (action = 9623)
0043-th step: f(x) = [-0.8884927 -0.23687603] (action = 4183)
Pareto set updated.
the number of Pareto frontiers = 10
0044-th step: f(x) = [-0.97621647 -0.0052244 ] (action = 3367)
Pareto set updated.
the number of Pareto frontiers = 9
0045-th step: f(x) = [-0.5974142 -0.99778865] (action = 9046)
0046-th step: f(x) = [-0.69847999 -0.99969655] (action = 9661)
0047-th step: f(x) = [-0.99999523 -0.89945685] (action = 1112)
0048-th step: f(x) = [-0.99988103 -0.67274056] (action = 2230)
0049-th step: f(x) = [-0.67089612 -0.99973586] (action = 7063)
0050-th step: f(x) = [-0.44743129 -0.8578429 ] (action = 6412)
Pareto set updated.
the number of Pareto frontiers = 10
disp_pareto_set=True と指定します。[11]:
policy = physbo.search.discrete_multi.Policy(test_X=test_X, num_objectives=2)
policy.set_seed(0)
res_random = policy.random_search(max_num_probes=num_random_search + num_bayes_search, simulator=simu, disp_pareto_set=True)
0001-th step: f(x) = [-0.99973003 -0.62334035] (action = 836)
Pareto set updated.
current Pareto set = [[-0.99973003 -0.62334035]] (steps = [1])
0002-th step: f(x) = [-0.99789981 -0.99866427] (action = 9404)
Pareto set updated.
current Pareto set = [[-0.99973003 -0.62334035]
[-0.99789981 -0.99866427]] (steps = [1 2])
0003-th step: f(x) = [-0.99090897 -0.46609239] (action = 4664)
Pareto set updated.
current Pareto set = [[-0.99090897 -0.46609239]] (steps = [3])
0004-th step: f(x) = [-0.92633083 -0.29208351] (action = 4780)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]] (steps = [4])
0005-th step: f(x) = [-0.67969326 -0.99981691] (action = 9566)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.67969326 -0.99981691]] (steps = [4 5])
0006-th step: f(x) = [-0.45601619 -0.99848443] (action = 8852)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.45601619 -0.99848443]] (steps = [4 6])
0007-th step: f(x) = [-0.92670204 -0.71508873] (action = 6088)
0008-th step: f(x) = [-0.58233995 -0.99952931] (action = 7060)
0009-th step: f(x) = [-0.99848229 -0.96780195] (action = 473)
0010-th step: f(x) = [-0.80479332 -0.99994946] (action = 7573)
0011-th step: f(x) = [-0.99700074 -0.99847873] (action = 1406)
0012-th step: f(x) = [-0.9992592 -0.93891121] (action = 6061)
0013-th step: f(x) = [-0.19963873 -0.93357674] (action = 5722)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.19963873 -0.93357674]] (steps = [ 4 13])
0014-th step: f(x) = [-0.98046765 -0.99294428] (action = 2309)
0015-th step: f(x) = [-0.99602549 -0.98620358] (action = 7989)
0016-th step: f(x) = [-0.99957128 -0.9973798 ] (action = 8484)
0017-th step: f(x) = [-0.52191048 -0.72845916] (action = 5405)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.52191048 -0.72845916]
[-0.19963873 -0.93357674]] (steps = [ 4 17 13])
0018-th step: f(x) = [-0.99916441 -0.40869572] (action = 2742)
0019-th step: f(x) = [-0.99480122 -0.7565076 ] (action = 1266)
0020-th step: f(x) = [-0.63329589 -0.63329589] (action = 5200)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.63329589 -0.63329589]
[-0.52191048 -0.72845916]
[-0.19963873 -0.93357674]] (steps = [ 4 20 17 13])
0021-th step: f(x) = [-0.95437918 -0.80142908] (action = 2487)
0022-th step: f(x) = [-0.99899466 -0.96646532] (action = 269)
0023-th step: f(x) = [-0.19473522 -0.99445365] (action = 8044)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.63329589 -0.63329589]
[-0.52191048 -0.72845916]
[-0.19963873 -0.93357674]
[-0.19473522 -0.99445365]] (steps = [ 4 20 17 13 23])
0024-th step: f(x) = [-0.99969529 -0.52395588] (action = 2135)
0025-th step: f(x) = [-0.59106078 -0.79258035] (action = 6206)
0026-th step: f(x) = [-0.78231041 -0.99997141] (action = 9079)
0027-th step: f(x) = [-0.99955573 -0.99930147] (action = 396)
0028-th step: f(x) = [-0.99825097 -0.99875436] (action = 9403)
0029-th step: f(x) = [-0.65387719 -0.99938669] (action = 9456)
0030-th step: f(x) = [-0.26132949 -0.87913689] (action = 5816)
Pareto set updated.
current Pareto set = [[-0.92633083 -0.29208351]
[-0.63329589 -0.63329589]
[-0.52191048 -0.72845916]
[-0.26132949 -0.87913689]
[-0.19963873 -0.93357674]
[-0.19473522 -0.99445365]] (steps = [ 4 20 17 30 13 23])
0031-th step: f(x) = [-0.74523952 -0.7724917 ] (action = 6301)
0032-th step: f(x) = [-0.33644513 -0.97772424] (action = 5530)
0033-th step: f(x) = [-0.99777557 -0.93373833] (action = 6470)
0034-th step: f(x) = [-0.9725524 -0.6296562] (action = 2277)
0035-th step: f(x) = [-0.99924826 -0.84674905] (action = 353)
0036-th step: f(x) = [-0.99743705 -0.17848438] (action = 2549)
Pareto set updated.
current Pareto set = [[-0.99743705 -0.17848438]
[-0.92633083 -0.29208351]
[-0.63329589 -0.63329589]
[-0.52191048 -0.72845916]
[-0.26132949 -0.87913689]
[-0.19963873 -0.93357674]
[-0.19473522 -0.99445365]] (steps = [36 4 20 17 30 13 23])
0037-th step: f(x) = [-0.99994916 -0.78013199] (action = 326)
0038-th step: f(x) = [-0.99887174 -0.86936149] (action = 5458)
0039-th step: f(x) = [-0.99362699 -0.99769786] (action = 9309)
0040-th step: f(x) = [-0.84889217 -0.99973225] (action = 10156)
0041-th step: f(x) = [-0.95713719 -0.09067194] (action = 4073)
Pareto set updated.
current Pareto set = [[-0.95713719 -0.09067194]
[-0.92633083 -0.29208351]
[-0.63329589 -0.63329589]
[-0.52191048 -0.72845916]
[-0.26132949 -0.87913689]
[-0.19963873 -0.93357674]
[-0.19473522 -0.99445365]] (steps = [41 4 20 17 30 13 23])
0042-th step: f(x) = [-0.17190645 -0.91382463] (action = 6120)
Pareto set updated.
current Pareto set = [[-0.95713719 -0.09067194]
[-0.92633083 -0.29208351]
[-0.63329589 -0.63329589]
[-0.52191048 -0.72845916]
[-0.26132949 -0.87913689]
[-0.17190645 -0.91382463]] (steps = [41 4 20 17 30 42])
0043-th step: f(x) = [-0.98406208 -0.94467587] (action = 7289)
0044-th step: f(x) = [-0.93974303 -0.92444262] (action = 2698)
0045-th step: f(x) = [-0.98414342 -0.84762781] (action = 1780)
0046-th step: f(x) = [-0.99699986 -0.98166426] (action = 7684)
0047-th step: f(x) = [-0.3868143 -0.99930896] (action = 8060)
0048-th step: f(x) = [-0.97964062 -0.65554315] (action = 2075)
0049-th step: f(x) = [-0.99907307 -0.73466786] (action = 4450)
0050-th step: f(x) = [-0.99720717 -0.85352507] (action = 865)
結果の確認
#### 評価値の履歴
[12]:
res_random.fx[0:res_random.num_runs]
[12]:
array([[-0.99973003, -0.62334035],
[-0.99789981, -0.99866427],
[-0.99090897, -0.46609239],
[-0.92633083, -0.29208351],
[-0.67969326, -0.99981691],
[-0.45601619, -0.99848443],
[-0.92670204, -0.71508873],
[-0.58233995, -0.99952931],
[-0.99848229, -0.96780195],
[-0.80479332, -0.99994946],
[-0.99700074, -0.99847873],
[-0.9992592 , -0.93891121],
[-0.19963873, -0.93357674],
[-0.98046765, -0.99294428],
[-0.99602549, -0.98620358],
[-0.99957128, -0.9973798 ],
[-0.52191048, -0.72845916],
[-0.99916441, -0.40869572],
[-0.99480122, -0.7565076 ],
[-0.63329589, -0.63329589],
[-0.95437918, -0.80142908],
[-0.99899466, -0.96646532],
[-0.19473522, -0.99445365],
[-0.99969529, -0.52395588],
[-0.59106078, -0.79258035],
[-0.78231041, -0.99997141],
[-0.99955573, -0.99930147],
[-0.99825097, -0.99875436],
[-0.65387719, -0.99938669],
[-0.26132949, -0.87913689],
[-0.74523952, -0.7724917 ],
[-0.33644513, -0.97772424],
[-0.99777557, -0.93373833],
[-0.9725524 , -0.6296562 ],
[-0.99924826, -0.84674905],
[-0.99743705, -0.17848438],
[-0.99994916, -0.78013199],
[-0.99887174, -0.86936149],
[-0.99362699, -0.99769786],
[-0.84889217, -0.99973225],
[-0.95713719, -0.09067194],
[-0.17190645, -0.91382463],
[-0.98406208, -0.94467587],
[-0.93974303, -0.92444262],
[-0.98414342, -0.84762781],
[-0.99699986, -0.98166426],
[-0.3868143 , -0.99930896],
[-0.97964062, -0.65554315],
[-0.99907307, -0.73466786],
[-0.99720717, -0.85352507]])
パレート解の取得
[13]:
front, front_num = res_random.export_pareto_front()
front, front_num
[13]:
(array([[-0.95713719, -0.09067194],
[-0.92633083, -0.29208351],
[-0.63329589, -0.63329589],
[-0.52191048, -0.72845916],
[-0.26132949, -0.87913689],
[-0.17190645, -0.91382463]]),
array([40, 3, 19, 16, 29, 41]))
解(評価値)のプロット
これ以降、図示する空間が \(y = (y_1, y_2)\) であり \(x = (x_1, x_2)\) ではないことにあらためて注意してください。
赤のプロットがパレート解です。
[14]:
fig, ax = plt.subplots(figsize=(7, 7))
physbo.search.utility.plot_pareto_front_all(res_random, ax=ax)
ax.set_xlim(-1, 0)
ax.set_ylim(-1, 0)
ax.set_title("random search")
[14]:
Text(0.5, 1.0, 'random search')
劣解領域 (dominated region) の体積を計算
res_random.pareto.volume_in_dominance(ref_min, ref_max) は、 ref_min, ref_max で指定された矩形(hyper-rectangle) 中の劣解領域体積を計算します。
[15]:
VID_random = res_random.pareto.volume_in_dominance([-1,-1],[0,0])
VID_random
[15]:
np.float64(0.2376881844865093)
ベイズ最適化
多目的の場合の bayes_search では、score には以下のいずれかを指定します。
HVPI (HyperVolume-based Probability of Improvement)
EHVI (Expected Hyper-Volume Improvement)
TS (Thompson Sampling)
以下、score を変えてそれぞれ 50回 (ランダムサーチ10回 + ベイズ最適化 40回) 評価を行います。
HVPI (HyperVolume-based Probability of Improvement)
多次元の目的関数空間における非劣解領域 (non-dominated region) の改善確率を score として求めます。
参考文献
Couckuyt, Ivo, Dirk Deschrijver, and Tom Dhaene. 「Fast calculation of multiobjective probability of improvement and expected improvement criteria for Pareto optimization.」 Journal of Global Optimization 60.3 (2014): 575-594.
[16]:
policy = physbo.search.discrete_multi.Policy(test_X=test_X, num_objectives=2)
policy.set_seed(seed)
policy.random_search(max_num_probes=num_random_search, simulator=simu, is_disp=False)
time_start = time.time()
res_HVPI = policy.bayes_search(
max_num_probes=num_bayes_search,
simulator=simu,
score="HVPI",
interval=10,
is_disp=False,
)
time_HVPI = time.time() - time_start
print(f"HVPI の計算時間: {time_HVPI} 秒")
HVPI の計算時間: 4.140035152435303 秒
パレート解のプロット
physbo.search.utility.plot_pareto_front_all に steps_end と steps_begin を指定することで、プロットするステップ数を指定できます。 style_common を指定することで、プロットの見た目を変更できます。 また、 style_dominated と style_pareto_front で、劣解領域とパレート解のプロットの見た目をそれぞれ変更できます。 ここでは最初のランダムサンプリングの結果を marker="+" でプロットし、その後のベイズ最適化の結果を marker="o" でプロットしています。
[17]:
fig, ax = plt.subplots(figsize=(7, 7))
physbo.search.utility.plot_pareto_front_all(
res_HVPI,
ax=ax,
steps_end=num_random_search,
style_common={"marker": "+"},
)
physbo.search.utility.plot_pareto_front_all(
res_HVPI,
ax=ax,
steps_begin=num_random_search,
style_common={"marker": "o"},
)
ax.set_xlim(-1, 0)
ax.set_ylim(-1, 0)
ax.set_title("HVPI")
[17]:
Text(0.5, 1.0, 'HVPI')
劣解領域体積
[18]:
VID_HVPI = res_HVPI.pareto.volume_in_dominance([-1,-1],[0,0])
VID_HVPI
[18]:
np.float64(0.3285497837573861)
ランダムサンプリングを50回おこなった結果と比べて、多くのパレート解が見つかっています。
EHVI (Expected Hyper-Volume Improvement)
多次元の目的関数空間における非劣解領域 (non-dominated region) の改善期待値を score として求めます。
参考文献
Couckuyt, Ivo, Dirk Deschrijver, and Tom Dhaene. 「Fast calculation of multiobjective probability of improvement and expected improvement criteria for Pareto optimization.」 Journal of Global Optimization 60.3 (2014): 575-594.
[19]:
policy = physbo.search.discrete_multi.Policy(test_X=test_X, num_objectives=2)
policy.set_seed(seed)
policy.random_search(max_num_probes=num_random_search, simulator=simu, is_disp=False)
time_start = time.time()
res_EHVI = policy.bayes_search(
max_num_probes=num_bayes_search,
simulator=simu,
score="EHVI",
interval=10,
is_disp=False,
)
time_EHVI = time.time() - time_start
print(f"EHVI の計算時間: {time_EHVI} 秒")
EHVI の計算時間: 34.10754203796387 秒
パレート解のプロット
[20]:
fig, ax = plt.subplots(figsize=(7, 7))
physbo.search.utility.plot_pareto_front_all(
res_EHVI,
ax=ax,
steps_end=num_random_search,
style_common={"marker": "+"},
)
physbo.search.utility.plot_pareto_front_all(
res_EHVI,
ax=ax,
steps_begin=num_random_search,
style_common={"marker": "o"},
)
ax.set_xlim(-1, 0)
ax.set_ylim(-1, 0)
ax.set_title("EHVI")
[20]:
Text(0.5, 1.0, 'EHVI')
劣解領域体積
[21]:
VID_EHVI = res_EHVI.pareto.volume_in_dominance([-1,-1],[0,0])
VID_EHVI
[21]:
np.float64(0.32220853509132785)
TS (Thompson Sampling)
参考文献
Yahyaa, Saba Q., and Bernard Manderick. 「Thompson sampling for multi-objective multi-armed bandits problem.」 Proc. Eur. Symp. Artif. Neural Netw., Comput. Intell. Mach. Learn.. 2015.
[22]:
policy = physbo.search.discrete_multi.Policy(test_X=test_X, num_objectives=2)
policy.set_seed(seed)
policy.random_search(max_num_probes=num_random_search, simulator=simu, is_disp=False)
time_start = time.time()
res_TS = policy.bayes_search(
max_num_probes=num_bayes_search,
simulator=simu,
score="TS",
interval=10,
num_rand_basis=500,
is_disp=False,
)
time_TS = time.time() - time_start
print(f"TS の計算時間: {time_TS} 秒")
TS の計算時間: 13.531005859375 秒
パレート解のプロット
[23]:
fig, ax = plt.subplots(figsize=(7, 7))
physbo.search.utility.plot_pareto_front_all(
res_TS,
ax=ax,
steps_end=num_random_search,
style_common={"marker": "+"},
)
physbo.search.utility.plot_pareto_front_all(
res_TS,
ax=ax,
steps_begin=num_random_search,
style_common={"marker": "o"},
)
ax.set_xlim(-1, 0)
ax.set_ylim(-1, 0)
ax.set_title("TS")
[23]:
Text(0.5, 1.0, 'TS')
劣解領域体積
[24]:
VID_TS = res_TS.pareto.volume_in_dominance([-1,-1],[0,0])
VID_TS
[24]:
np.float64(0.3061697389817548)
比較
これまでの結果を比較してみましょう。
[25]:
import pandas as pd
pd.DataFrame({
"アルゴリズム": ["HVPI", "EHVI", "TS"],
"計算時間": [time_HVPI, time_EHVI, time_TS],
"劣解領域体積": [VID_HVPI, VID_EHVI, VID_TS]
})
[25]:
| アルゴリズム | 計算時間 | 劣解領域体積 | |
|---|---|---|---|
| 0 | HVPI | 4.140035 | 0.328550 |
| 1 | EHVI | 34.107542 | 0.322209 |
| 2 | TS | 13.531006 | 0.306170 |
付録:全探索
random_search で max_num_probes に全データ数 (N = test_X.shape[0]) を渡すと手軽に全探索できます。[26]:
test_X_sparse = physbo.search.utility.make_grid(min_X=min_X, max_X=max_X, num_X=21)
simu_sparse = physbo.search.utility.Simulator(test_X_sparse, vlmop2_minus)
policy = physbo.search.discrete_multi.Policy(test_X=test_X_sparse, num_objectives=2)
policy.set_seed(0)
N = test_X_sparse.shape[0]
res_all = policy.random_search(max_num_probes=N, simulator=simu_sparse, is_disp=False)
パレート解のプロット
[27]:
fig, ax = plt.subplots(figsize=(7, 7))
physbo.search.utility.plot_pareto_front_all(res_all, ax=ax)
[27]:
array([[<Axes: xlabel='Objective 1', ylabel='Objective 2'>]], dtype=object)