我试图让一个简单的PyMC2模型在PyMC3中运行。我已经让模型运行但是模型对变量给出了非常不同的MAP估计。这是我的PyMC2模型:
import pymc
theta = pymc.Normal('theta', 0, .88)
X1 = pymc.Bernoulli('X2', p=pymc.Lambda('a', lambda theta=theta:1./(1+np.exp(-(theta-(-0.75))))), value=[1],observed=True)
X2 = pymc.Bernoulli('X3', p=pymc.Lambda('b', lambda theta=theta:1./(1+np.exp(-(theta-0)))), value=[1],observed=True)
model = pymc.Model([theta, X1, X2])
mcmc = pymc.MCMC(model)
mcmc.sample(iter=25000, burn=5000)
trace = (mcmc.trace('theta')[:])
print "\nThe MAP value for theta is", trace.sum()/len(trace)
这似乎按预期工作。我在制定如何在PyMC3中使用等效的pymc.Lambda对象时遇到了各种各样的麻烦。我最终遇到了确定性对象。以下是我的代码:
import pymc3
with pymc3.Model() as model:
theta = pymc3.Normal('theta', 0, 0.88)
X1 = pymc3.Bernoulli('X1', p=pymc3.Deterministic('b', 1./(1+np.exp(-(theta-(-0.75))))), observed=[1])
X2 = pymc3.Bernoulli('X2', p=pymc3.Deterministic('c', 1./(1+np.exp(-(theta-(0))))), observed=[1])
start=pymc3.find_MAP()
step=pymc3.NUTS(state=start)
trace = pymc3.sample(20000, step, njobs=1, progressbar=True)
pymc3.traceplot(trace)
我遇到的问题是我使用PyMC2对θ的MAP估计值是~0.68(正确),而PyMC3给出的估计值是~0.26(不正确)。我怀疑这与我定义确定性函数的方式有关。 PyMC3不允许我使用lambda函数,所以我只需要在线编写表达式。当我尝试使用lambda theta = theta:...时出现此错误:
AsTensorError: ('Cannot convert <function <lambda> at 0x157323e60> to TensorType', <type 'function'>)
与Theano有什么关系?任何建议将不胜感激!
答案 0 :(得分:2)
当你在确定性中使用theano tensor
而不是numpy函数时,它会起作用。
import pymc3
import theano.tensor as tt
with pymc3.Model() as model:
theta = pymc3.Normal('theta', 0, 0.88)
X1 = pymc3.Bernoulli('X1', p=pymc3.Deterministic('b', 1./(1+tt.exp(-(theta-(-0.75))))), observed=[1])
X2 = pymc3.Bernoulli('X2', p=pymc3.Deterministic('c', 1./(1+tt.exp(-(theta-(0))))), observed=[1])
start=pymc3.find_MAP()
step=pymc3.NUTS(state=start)
trace = pymc3.sample(20000, step, njobs=1, progressbar=True)
print "\nThe MAP value for theta is", np.median(trace['theta'])
pymc3.traceplot(trace);
这是输出:
答案 1 :(得分:0)
万一其他人遇到同样的问题,我想我找到了答案。在尝试不同的采样算法后,我发现:
我在其他地方读到NUTS采样器不能与确定性一起使用。我不知道为什么。也许这也是find_MAP的情况?但是现在我会坚持使用Metropolis。
答案 2 :(得分:0)
此外,NUTS不处理离散变量。如果你想使用NUTS,你必须拆分采样器:
step1 = pymc3.NUTS([theta])
step2 = pymc3.BinaryMetropolis([X1,X2])
trace = pymc3.sample(10000, [step1, step2], start)
编辑: 错过了&#39; b&#39;和&#39; c&#39;是内联定义的。从NUTS函数调用中删除它们
答案 3 :(得分:0)
MAP值未定义为分布的均值,而是最大值。使用pymc2
,您可以找到它:
M = pymc.MAP(model)
M.fit()
theta.value
返回array(0.6253614422469552)
这与您在find_MAP
pymc3
中找到的MAP一致,您称之为start
:
{'theta': array(0.6253614811102668)}
哪个是更好的采样器的问题是不同的,并且不依赖于MAP的计算。 MAP计算是一种优化。
请参阅pymc2
的{{3}}。