我试图在pymc3中创建一个三级逻辑回归模型。有顶级,中级和个人级别,其中中级系数是从顶级系数估算的。但是,我很难指定适合中级的数据结构。在pymc3中创建一个三级逻辑回归模型
这里是我的代码:
with pm.Model() as model:
# Hyperpriors
top_level_tau = pm.HalfNormal('top_level_tau', sd=100.)
mid_level_tau = pm.HalfNormal('mid_level_tau', sd=100.)
# Priors
top_level = pm.Normal('top_level', mu=0., tau=top_level_tau, shape=k_top)
mid_level = [pm.Normal('mid_level_{}'.format(j),
mu=top_level[mid_to_top_idx[j]],
tau=mid_level_tau)
for j in range(k_mid)]
intercept = pm.Normal('intercept', mu=0., sd=100.)
# Model prediction
yhat = pm.invlogit(mid_level[mid_to_bot_idx] + intercept)
# Likelihood
yact = pm.Bernoulli('yact', p=yhat, observed=y)
,我发现了错误"only integer arrays with one element can be converted to an index"
(第16行),我认为这是关系到一个事实,即mid_level
变量是一个列表,而不是一个适当的pymc容器。 (我没有在pymc3源代码中看到Container类。)
任何帮助,将不胜感激。
编辑:添加一些模拟数据
y = np.array([0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0])
mid_to_bot_idx = np.array([0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 3, 2, 3, 3, 3, 3, 2, 2, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 3, 3, 2, 3, 2, 3, 3, 2, 2, 3, 2, 2, 3, 3, 3, 3, 2, 2, 2, 3, 2, 3, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 3, 2, 2, 3, 3, 2, 2, 3, 2])
mid_to_top_idx = np.array([0, 0, 1, 1])
k_top = 2
k_mid = 4
编辑#2:
似乎有是几种不同的方法来解决这个问题,但没有一个是完全令人满意:
1)可以将模型重新组合为:
with pm.Model() as model:
# Hyperpriors
top_level_tau = pm.HalfNormal('top_level_tau', sd=100.)
mid_level_tau = pm.HalfNormal('mid_level_tau', sd=100.)
# Priors
top_level = pm.Normal('top_level', mu=0., tau=top_level_tau, shape=k_top)
mid_level = pm.Normal('mid_level', mu=0., tau=mid_level_tau, shape=k_top)
intercept = pm.Normal('intercept', mu=0., sd=100.)
# Model prediction
yhat = pm.invlogit(top_level[top_to_bot_idx] + mid_level[mid_to_bot_idx] + intercept)
# Likelihood
yact = pm.Bernoulli('yact', p=yhat, observed=y)
这似乎工作,虽然我无法弄清楚如何将它扩展到所有中等水平群体的中等水平差异不是恒定的情况。
2),可以使用theano.tensor.stack包裹中级系数为Theano张量:即
import theano.tensor as tt
mid_level = tt.stack([pm.Normal('mid_level_{}'.format(j),
mu=top_level[mid_to_top_idx[j]],
tau=mid_level_tau)
for j in range(k_mid)])
但这似乎对我的实际数据集运行非常缓慢(30K观察) ,并且使得绘图不方便(每个中间级别系数使用pm.traceplot
获得它自己的轨迹)。
无论如何,来自开发者的一些建议/意见将不胜感激。
@gung现在看起来好吗? – vbox
谢谢,这太好了。关于Python中编码的问题在这里是脱离主题的,但可以在[SO]的主题上讨论。如果您等待,我们会尝试在那里迁移您的问题。 – gung
我不同意这是题外话题:这不是一个通用的python编码问题。这个问题是关于用一个成熟的python统计软件包来实现一个统计模型 - 答案很可能是以不同的方式表示模型。 – JBWhitmore