如何在PyMC3中定义一个模型,使一个参数在多个条件下保持相同值
我想写一个模型,像下面这样。主要的想法是我有几个条件(或者说处理),所有的参数都是针对每个条件单独估计的,除了kappa参数,它在所有条件下都是一样的。
with pm.Model() as model:
trace_per_condition = []
# define the kappa hyperparameter
kappa = pm.Gamma('kappa', 1, 0.1)
for condition in range(0, ncond):
z_cond = z[condition]
# define the mu hyperparameter
mu = pm.Beta('mu', 1, 1)
# define the prior
theta = pm.Beta('theta', mu * kappa, (1 - mu) * kappa, shape=len(z_cond))
# define the likelihood
y = pm.Binomial('y', p=theta, n=trials, observed=z_cond)
# Generate a MCMC chain
start = pm.find_MAP()
step1 = pm.Metropolis([theta, mu])
step2 = pm.NUTS([kappa])
trace = pm.sample(1000, [step1, step2], progressbar=False)
trace_per_condition.append(trace)
当我运行这个模型时,我收到了以下信息。
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/gradient.py:513: UserWarning: grad method was asked to compute the gradient with respect to a variable that is not part of the computational graph of the cost, or is used only by a non-differentiable operator: mu handle_disconnected(elem)
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/gradient.py:533: UserWarning: grad method was asked to compute the gradient with respect to a variable that is not part of the computational graph of the cost, or is used only by a non-differentiable operator: <DisconnectedType>
handle_disconnected(rval[i])
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/gradient.py:513: UserWarning: grad method was asked to compute the gradient with respect to a variable that is not part of the computational graph of the cost, or is used only by a non-differentiable operator: theta
handle_disconnected(elem)
Traceback (most recent call last):
File "<stdin>", line 46, in <module>
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/tuning/starting.py", line 80, in find_MAP
start), fprime=grad_logp_o, disp=disp, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 777, in fmin_bfgs
res = _minimize_bfgs(f, x0, args, fprime, callback=callback, **opts)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 832, in _minimize_bfgs
gfk = myfprime(x0)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 281, in function_wrapper
return function(*(wrapper_args + args))
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/tuning/starting.py", line 75, in grad_logp_o
return nan_to_num(-dlogp(point))
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/blocking.py", line 119, in __call__
return self.fa(self.fb(x))
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/model.py", line 284, in __call__
return self.f(**state)
File "/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/compile/function_module.py", line 516, in __call__
self[k] = arg
File "/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/compile/function_module.py", line 452, in __setitem__
self.value[item] = value
File "/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/compile/function_module.py", line 413, in __setitem__
"of the inputs of your function for duplicates." % str(item))
TypeError: Ambiguous name: mu - please check the names of the inputs of your function for duplicates.
编辑
根据chris-fonnesbeck的回答,我尝试了以下方法:
with pm.Model() as model:
trace_per_condition = []
# define the kappa hyperparameter
kappa = pm.Gamma('kappa', 1, 0.1)
for condition in range(0, ncond):
z_cond = z[condition]
# define the mu hyperparameter
mu = pm.Beta('mu_%i' % condition, 1, 1)
# define the prior
theta = pm.Beta('theta_%i' % condition, mu * kappa, (1 - mu) * kappa, shape=len(z_cond))
# define the likelihood
y = pm.Binomial('y_%i' % condition, p=theta, n=trials, observed=z_cond)
# Generate a MCMC chain
start = pm.find_MAP()
step1 = pm.Metropolis([theta, mu])
step2 = pm.NUTS([kappa])
trace = pm.sample(10000, [step1, step2], start=start, progressbar=False)
trace_per_condition.append(trace)
我遇到了这个错误:
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/gradient.py:513:
UserWarning: grad method was asked to compute the gradient with respect to a variable
that is not part of the computational graph of the cost, or is used only by a
non-differentiable operator: mu_1
handle_disconnected(elem)
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/gradient.py:533:
UserWarning: grad method was asked to compute the gradient with respect to a variable
that is not part of the computational graph of the cost, or is used only by a
non-differentiable operator: <DisconnectedType>
handle_disconnected(rval[i])
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/gradient.py:513:
UserWarning: grad method was asked to compute the gradient with respect to a variable
that is not part of the computational graph of the cost, or is used only by a
non-differentiable operator: theta_1
handle_disconnected(elem)
Traceback (most recent call last):
File "<stdin>", line 43, in <module>
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/tuning/starting.py", line 80, in find_MAP
start), fprime=grad_logp_o, disp=disp, *args, **kwargs)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 777, in fmin_bfgs
res = _minimize_bfgs(f, x0, args, fprime, callback=callback, **opts)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 837, in _minimize_bfgs
old_fval = f(x0)
File "/usr/lib/python2.7/dist-packages/scipy/optimize/optimize.py", line 281, in function_wrapper
return function(*(wrapper_args + args))
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/tuning/starting.py", line 72, in logp_o
return nan_to_high(-logp(point))
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/blocking.py", line 119, in __call__
return self.fa(self.fb(x))
File "/usr/local/lib/python2.7/dist-packages/pymc-3.0-py2.7.egg/pymc/model.py", line 283, in __call__
return self.f(**state)
File "/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/theano/compile/function_module.py", line 482, in __call__
raise TypeError("Too many parameter passed to theano function")
TypeError: Too many parameter passed to theano function
这些用户警告与起始点的优化有关,如果我不使用pm.find_MAP(),这些警告就会消失。但其他的错误依然存在。
2 个回答
3
如果你在一个循环里定义PyMC对象,你需要在每次循环时给它们不同的名字。比如你可以这样定义:
mu = pm.Beta('mu_%i' % condition, 1, 1)
这样做应该能解决你遇到的错误。
4
我注意到你在每次添加条件的时候都在进行采样,我觉得你可能想把这个操作放到循环外面去做。
另外,你不需要为每个条件单独定义一个变量来存储 mu、theta 和 y。比如,如果你的数据在 data
的列中,你应该可以这样做:
with pm.Model() as model:
kappa = pm.Gamma('kappa', 1, 0.1)
mu = pm.Beta('mu', 1, 1, shape=ncond)
mu_c = mu[data.condition]
theta = pm.Beta('theta', mu_c * kappa, (1 - mu_c) * kappa, shape=len(data))
y = pm.Binomial('y', p=theta, n=data.trials, observed=data.z_cond)