我想知道为什么采样器在逐步采样时速度非常慢。例如,如果我运行:
mcmc = MCMC(model)
mcmc.sample(1000)
采样速度很快。但是,如果我运行:
mcmc = MCMC(model)
for i in arange(1000):
mcmc.sample(1)
采样速度较慢(采样越多,速度越慢)。
如果您想知道我为什么要问这个.. 好吧,我需要逐步采样,因为我想在采样器的每一步之后对变量的值执行一些操作。
有没有办法加快速度?
先感谢您!
- - - - - - - - - 编辑 - - - - - - - - - - - - - - - - ------------------------------
在这里,我更详细地介绍了具体问题:
我有两个竞争模型,它们是更大模型的一部分,该模型具有一个分类变量,作为两者之间的“开关”。
在这个玩具示例中,我有观察到的向量“Y”,可以用泊松或几何分布来解释。分类变量“switch_model”在 = 0 时选择几何模型,在 =1 时选择泊松模型。
在每个样本之后,如果 switch_model 选择几何模型,我希望泊松模型的变量不要更新,因为它们不会影响可能性,因此它们只是逐渐消失。如果 switch_model 选择 Poisson 模型,则相反。
基本上,我在每一步所做的就是通过手动将其向后退一步来“更改”未选择模型的值。
我希望我的解释和注释代码足够清楚。如果您需要更多详细信息,请告诉我。
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()