Я хотел бы знать, почему сэмплер невероятно медленный при пошаговой выборке. Например, если я запускаю:
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 выбирает модель Пуассона.
В основном то, что я делаю на каждом шаге, — это «изменение» значения невыбранной модели, возвращая ее вручную на один шаг назад.
Я надеюсь, что мое объяснение и закомментированный код будут достаточно понятными. Дайте мне знать, если вам нужна дополнительная информация.
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()