在PyMC3中对多维p使用类别分类

时间:2018-07-30 22:49:52

标签: theano pymc3

当我尝试使用pm.Categorical一次对许多实例进行采样时(使用多维p或使用theano.scan)时,我遇到了问题。去这里最好的方法是什么?我的目标是根据每个人每次回应的概率,为每个人的每个抽奖抽取一个回应。

这是许多人的一个实际例子,一画:

import pymc3 as pm
import theano.tensor as T
import numpy as np

actions = T.as_tensor_variable(np.array([0, 1, 2]))  # indiv0 selects response0, indiv1 response1, etc.
with pm.Model() as model:
    p = pm.Beta('p', alpha=2, beta=2, shape=[3, 3])  # prob. for each indiv. for each response
    actions = pm.Categorical('actions', p=p, observed=actions)
    trace = pm.sample()

这里一切都很好。该模型对9个p采样,每个个体和每个响应一个。但是我想做的是为每个人采样几个响应。我首先尝试在操作数据中添加试验维度:

n_trials = 10
actions = T.as_tensor_variable(np.array([[0, 1, 2]] * n_trials))  # same thing, 10 trials
with pm.Model() as model:
    p = pm.Beta('p', alpha=2, beta=2, shape=[3, 3])  # same as above, but more trials
    actions = pm.Categorical('actions', p=p, observed=actions)
    trace = pm.sample()

显然,这会导致错误:

Wrong number of dimensions: expected 1, got 2 with shape (10, 3).

令人惊讶的是,当我为每个样本,每个个体和每个响应绘制一个单独的p时,也会导致错误:

p = pm.Beta('p', alpha=2, beta=2, shape=[n_trials, 3, 3])

似乎pm.Categorical仅接受二维p。为了保持p二维,我尝试扫描:

actions = T.as_tensor_variable(np.array([[0, 1, 2]] * 10)
with pm.Model() as model:
    p = pm.Beta('p', alpha=2, beta=2, shape=[3, 3])  # same as above
    actions, _ = theano.scan(fn=lambda action, p: pm.Categorical('actions', p=p, observed=action),
                             sequences=[actions],
                             non_sequences=[p])
    trace = pm.sample()

代码失败,并显示以下错误消息:

theano.gof.fg.MissingInputError: Input 0 of the graph (indices start from 0), used to compute Elemwise{Cast{int64}}(<TensorType(int32, vector)>), was not provided and not given a value. Use the Theano flag exception_verbosity='high', for more information on this error.

所以也许不能在theano.scan中使用pm.Categorical?关于如何解决此问题的任何帮助将超级有帮助!

1 个答案:

答案 0 :(得分:0)

以下解决了我的问题。我做了1维和p 2维的动作:

n_trials, n_subj, n_actions = 10, 3, 3

actions = T.as_tensor_variable(np.array([0, 1, 2] * n_trials))  # shape (30, ) instead of (10, 3)
with pm.Model() as model:
    p = pm.Uniform('p', lower=0, upper=1, shape=[n_subj, n_actions])
    indiv = T.tile(T.arange(n_subj), n_trials)
    p = p[indiv]
    actions = pm.Categorical('actions', p=p, observed=actions)
    trace = pm.sample()