Metropolis Hastings 法の説明と Python による実装
MCMC(マルコフ連鎖モンテカルロ法)
ある分布
そのようなケースの対処法として MCMC(マルコフ連鎖モンテカルロ法) がある。これは
Metropolis Hastings 法
Metropolis Hastings 法においては、ユーザーが 提案分布 (proposal distribution) を指定してあげる必要がある。"提案" とは、サンプルが
単純な例として、
とおける。言い換えると、提案分布
という式になる。
この提案分布
- 初期値
を適当に定めるX_1 = x_1 -
に対して以下を十分な回数繰り返すt \geq 1 -
からQ(y|x_t) という値をサンプルする(提案)y -
を計算するA = \min \left(1, \dfrac{\pi(y)Q(x_t|y)}{\pi(x_t)Q(y|x_t)} \right) - 確率
で提案を受諾し、A とする. 確率x_{t+1} = y で提案を拒否し1-A に留まるx_{t+1} = x_t
-
実装
例として、
という分布からサンプルを得たいとする。もちろん、このような単純な分布であれば MCMC をわざわざ使う必要はないが、あくまで簡単な例としてである。
提案分布
とよりシンプルに書ける。
この Metropolis 法を Python で実装してみると、以下のようになる。
import numpy as np
def pi(x):
if x >= 0:
return np.exp(-x)
else:
return 0
xs = []
xs.append(10) # 初期値を適当に 10 と定めた
for i in range(10000):
y = np.random.normal(xs[i], 1) # 提案値
a = min(1, pi(y) / pi(xs[i]))
u = np.random.rand() # 0 ~ 1 の一様乱数を生成
if u < a: # 受諾
xs.append(y)
else: # 拒否
xs.append(xs[i])
さて、このように計算された xs
は
import matplotlib.pyplot as plt
%matplotlib inline
plt.hist(xs, bins=20)
確かに、右肩下がりの指数分布の形になっていることがわかる。
また、最初の100個のサンプルと次の100個のサンプルを比べてみる。
plt.hist(xs[0:100], bins=20)
plt.hist(xs[100:200], bins=20)
後者の方が、何となく右肩下がりがハッキリと確認できるように見える。このように試行回数を増やすことで、
Discussion