Python 如何在PyMC3中定义一个模型,其中一个参数在多个条件下约束为相同的值

Python 如何在PyMC3中定义一个模型,其中一个参数在多个条件下约束为相同的值,python,bayesian,pymc3,Python,Bayesian,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_co

我想写一个模型,就像下面的那个。主要的想法是,我有几个条件(或治疗),所有的参数都是独立估计每个条件,除了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.
我得到一个错误:

/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
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/Theano/gradient.py:513:
用户警告:要求grad方法计算变量的梯度
这不是成本计算图的一部分,或仅由
不可微算子:mu_1
断开手柄(elem)
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/Theano/gradient.py:533:
用户警告:要求grad方法计算变量的梯度
这不是成本计算图的一部分,或仅由
不可微算子:
句柄\u已断开(rval[i])
/usr/local/lib/python2.7/dist-packages/Theano-0.6.0-py2.7.egg/Theano/gradient.py:513:
用户警告:要求grad方法计算变量的梯度
这不是成本计算图的一部分,或仅由
不可微算子:θ_1
断开手柄(elem)
回溯(最近一次呼叫最后一次):
文件“”,第43行,在
文件“/usr/local/lib/python2.7/dist packages/pymc-3.0-py2.7.egg/pymc/tuning/starting.py”,第80行,在find_映射中
开始),fprime=grad\u logp\u o,disp=disp,*args,**kwargs)
文件“/usr/lib/python2.7/dist packages/scipy/optimize/optimize.py”,第777行,在fmin_bfgs中
res=\u最小化\u bfgs(f,x0,args,fprime,callback=callback,**选项)
文件“/usr/lib/python2.7/dist packages/scipy/optimize/optimize.py”,第837行,在
旧的fval=f(x0)
文件“/usr/lib/python2.7/dist packages/scipy/optimize/optimize.py”,第281行,在函数包装器中
返回函数(*(包装器参数+参数))
文件“/usr/local/lib/python2.7/dist packages/pymc-3.0-py2.7.egg/pymc/tuning/starting.py”,第72行,在logp_o中
将nan_返回至_高(-logp(点))
文件“/usr/local/lib/python2.7/dist packages/pymc-3.0-py2.7.egg/pymc/blocking.py”,第119行,在调用__
返回self.fa(self.fb(x))
文件“/usr/local/lib/python2.7/dist packages/pymc-3.0-py2.7.egg/pymc/model.py”,第283行,在调用中__
返回self.f(**状态)
文件“/usr/local/lib/python2.7/dist packages/Theano-0.6.0-py2.7.egg/Theano/compile/function_module.py”,第482行,在调用中__
raise TypeError(“传递给THANO函数的参数太多”)
TypeError:传递给theano函数的参数太多

UserWarning与起始点的优化有关,如果我不使用pm.find_MAP(),它将被删除。其余的错误仍然存在。

如果在循环中定义PyMC对象,则必须在每次迭代中为它们指定不同的名称。例如,您可以定义:

mu = pm.Beta('mu_%i' % condition, 1, 1)

这应该可以消除您得到的错误。

我注意到的一件事是,您每次添加条件时都在采样,我认为您可能希望将其从循环中拉出来

此外,您不需要为每个条件的每个mu、θ、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)

谢谢,这很有道理,但现在我又犯了一个错误。我编辑问题以添加新错误。
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)