ステップごとにサンプリングするときにサンプラーが非常に遅い理由を知りたいです。たとえば、次のように実行すると:
mcmc = MCMC(model)
mcmc.sample(1000)
サンプリングは高速です。ただし、実行すると:
mcmc = MCMC(model)
for i in arange(1000):
mcmc.sample(1)
サンプリングは遅くなります (サンプリングが多いほど遅くなります)。
なぜ私がこれを尋ねているのか疑問に思っているなら..まあ、サンプラーの各ステップの後に変数の値に対していくつかの操作を実行したいので、段階的なサンプリングが必要です。
それをスピードアップする方法はありますか?
前もって感謝します!
- - - - - - - - - 編集 - - - - - - - - - - - - - - - - ------------------------------
ここで、特定の問題をより詳細に提示します。
競合する 2 つのモデルがあり、それらは 2 つの間の「スイッチ」として機能するカテゴリ変数を持つより大きなモデルの一部です。
このおもちゃの例では、観測されたベクトル 'Y' があり、これはポアソン分布または幾何分布で説明できます。カテゴリ変数 'switch_model' は、= 0 の場合は幾何モデルを選択し、=1 の場合はポアソン モデルを選択します。
各サンプルの後、switch_model が幾何学的モデルを選択した場合、ポアソン モデルの変数は更新されないようにします。これは、可能性に影響を与えていないため、単に漂流しているだけだからです。switch_model がポアソン モデルを選択する場合は、その逆です。
基本的に、各ステップで行うことは、選択されていないモデルの値を手動で 1 ステップ戻すことによって「変更」することです。
私の説明とコメント付きのコードが十分に明確になることを願っています。詳細が必要な場合はお知らせください。
import numpy as np
import pymc as pm
import pandas as pd
import matplotlib.pyplot as plt
# OBSERVED VALUES
Y = np.array([0, 1, 2, 3, 8])
# PRIOR ON THE MODELS
pi = (0.5, 0.5)
switch_model = pm.Categorical("switch_model", p = pi)
# switch_model = 0 for Geometric, switch_model = 1 for Poisson
p = pm.Uniform('p', lower = 0, upper = 1) # Prior of the parameter of the geometric distribution
mu = pm.Uniform('mu', lower = 0, upper = 10) # Prior of the parameter of the Poisson distribution
# LIKELIHOOD
@pm.observed
def Ylike(value = Y, mu = mu, p = p, M = switch_model):
if M == 0:
out = pm.geometric_like(value+1, p)
elif M == 1:
out = pm.poisson_like(value, mu)
return out
model = pm.Model([Ylike, p, mu, switch_model])
mcmc = pm.MCMC(model)
n_samples = 5000
traces = {}
for var in mcmc.stochastics:
traces[str(var)] = np.zeros(n_samples)
bar = pm.progressbar.progress_bar(n_samples)
bar.update(0)
mcmc.sample(1, progress_bar=False)
for var in mcmc.stochastics:
traces[str(var)][0] = mcmc.trace(var)[-1]
for i in np.arange(1,n_samples):
mcmc.sample(1, progress_bar=False)
bar.update(i)
for var in mcmc.stochastics:
traces[str(var)][i] = mcmc.trace(var)[-1]
if mcmc.trace('switch_model')[-1] == 0: # Gemetric wins
traces['mu'][i] = traces['mu'][i-1] # One step back for the sampler of the Poisson parameter
mu.value = traces['mu'][i-1]
elif mcmc.trace('switch_model')[-1] == 1: # Poisson wins
traces['p'][i] = traces['p'][i-1] # One step back for the sampler of the Geometric parameter
p.value = traces['p'][i-1]
print '\n\n'
traces=pd.DataFrame(traces)
traces['mu'][traces['switch_model'] == 0] = np.nan
traces['p'][traces['switch_model'] == 1] = np.nan
print traces.describe()
traces.plot()
plt.show()