Можно ли использовать операторы if в детерминированной функции PyMC?
После прочтения вероятностного программирования и байесовских методов для хакеров Кэма Дэвидсона-Пилона я решил попробовать свои силы в задаче изучения скрытой марковской модели (HMM) с PyMC. Пока что код не взаимодействует, но из-за устранения неполадок я чувствую, что сузил источник проблемы.
Разбивая код на более мелкие порции и сосредотачиваясь на начальной вероятности и вероятностях выбросов при t=0, я могу узнать параметры излучения / наблюдения одного состояния в момент времени t=0. Однако, как только я добавляю в другое состояние (всего два состояния), результаты обучения параметров идентичны (и неверны) независимо от ввода данных. Итак, я чувствую, что я сделал что-то не так в @pm.deterministic
часть кода, которая не позволяет мне пробовать из Init
начальная функция вероятности.
С помощью этой части кода я стремлюсь узнать начальную вероятность p_bern
и вероятности выбросов p_0
а также p_1
соответствует состояниям 0 и 1 соответственно. Эмиссия зависит от состояния, которое я пытаюсь выразить своим @pm.deterministic
функция. Могу ли я использовать оператор if в этой детерминированной функции? Кажется, это корень проблемы.
# This code is to test the ability to discern between two states with emissions
import numpy as np
import pymc as pm
from matplotlib import pyplot as plt
N = 1000
state = np.zeros(N)
data = np.zeros(shape=N)
# Generate data
for i in range(N):
state[i] = pm.rbernoulli(p=0.3)
for i in range(N):
if state[i]==0:
data[i] = pm.rbernoulli(p=0.4)
elif state[i]==1:
data[i] = pm.rbernoulli(p=0.8)
# Prior on probabilities
p_bern = pm.Uniform("p_S", 0., 1.)
p_0 = pm.Uniform("p_0", 0., 1.)
p_1 = pm.Uniform("p_1", 0., 1.)
Init = pm.Bernoulli("Init", p=p_bern) # Bernoulli node
@pm.deterministic
def p_T(Init=Init, p_0=p_0, p_1=p_1, p_bern=p_bern):
if Init==0:
return p_0
elif Init==1:
return p_1
obs = pm.Bernoulli("obs", p=p_T, value=data, observed=True)
model = pm.Model([obs, p_bern, p_0, p_1])
mcmc = pm.MCMC(model)
mcmc.sample(20000, 10000)
pm.Matplot.plot(mcmc)
Я уже пытался следующее безрезультатно:
- Использовать
@pm.potential
декоратор для создания совместного распространения - Изменение места расположения моего
Init
местоположение (вы можете увидеть мой комментарий в коде, где я не уверен, где его разместить) - Использовать
@pm.stochastic
похоже на это
Редактировать: Согласно предложению Криса, я переместил узел Бернулли за пределы детерминизма. Я также обновил код для упрощения модели (наблюдение Бернулли вместо многочлена) для упрощения поиска неисправностей.
Спасибо за ваше время и внимание. Любые отзывы тепло принимаются. Кроме того, если мне не хватает какой-либо информации, пожалуйста, дайте мне знать!
2 ответа
Я бы убрал эту стохастичность из детерминизма. Предполагается, что значение детерминированного узла полностью определяется значением его родителей. Наличие случайной переменной, скрытой в узле, нарушает это.
Зачем создавать точку Бернулли и передавать ее в качестве аргумента детерминистическому?
Основываясь на предоставленной вами обновленной информации, вот код, который работает:
import numpy as np
import pymc as pm
from matplotlib import pyplot as plt
N = 1000
state = np.zeros(N)
data = np.zeros(shape=N)
# Generate data
state = pm.rbernoulli(p=0.3, size=N)
data = [int(pm.rbernoulli(0.8*s or 0.4)) for s in state]
# Prior on probabilities
p_S = pm.Uniform("p_S", 0., 1.)
p_0 = pm.Uniform("p_0", 0., 1.)
p_1 = pm.Uniform("p_1", 0., 1.)
# Use values of Init as indices to probabilities
Init = pm.Bernoulli("Init", p=p_S, size=N) # Bernoulli node
p_T = pm.Lambda('p_T', lambda p_0=p_0, p_1=p_1, i=Init: np.array([p_0, p_1])[i.astype(int)])
obs = pm.Bernoulli("obs", p=p_T, value=data, observed=True)
model = pm.MCMC(locals())
model.sample(20000, 10000)
model.summary()
Обратите внимание, что на этапе генерации данных я использую состояния для индексации соответствующей истинной вероятности. По сути, я делаю то же самое в спецификации p_T
, Кажется, он работает достаточно хорошо, но учтите, что в зависимости от того, где что-то инициализируется, два значения p_0
а также p_1
может в конечном итоге соответствовать одному из истинных значений (ничто не может ограничить одно быть больше другого). Итак, ценность p_S
может закончиться как дополнение к вероятности истинного состояния.