当我尝试使用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?关于如何解决此问题的任何帮助将超级有帮助!
答案 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()