在pymc3

时间:2017-03-27 17:12:43

标签: python bayesian survival-analysis mcmc pymc3

我有一个随着时间的推移观察的分层logit。在Carter 2010之后,我包含了时间,时间^ 2和时间^ 3项。在添加时间变量之前,模型使用Metropolis或NUTS进行混合。 HamiltonianMC失败了。 NUTS和Metropolis也与时俱进。但NUTS和Metropolis在时间^ 2和时间^ 3失败,但它们以不同的方式失败并以令人费解的方式。然而,与其他因模型规格更明显的原因而失败的模型不同,ADVI仍然给出了估计,(ELBO不是inf)。

  • NUTS要么提前停止(上次进行60次迭代),要么进展太快并返回一个空的跟踪图,其中包含关于varnames的错误。
  • Metropolis在出现尺寸不匹配错误时立即出错。它看起来像this github error中的那个,但我使用的是伯努利结果,而不是负二项式。错误的结尾如下:ValueError: Input dimension mis-match. (input[0].shape[0] = 1, input[4].shape[0] = 18)
  • 当我尝试HamiltonianMC时,我得到一条空迹。它返回没有混合的起始值
  • ADVI给了我一个平均值和标准差。
  • 我大量增加了ADVI迭代次数。它给出了非常接近相同的起点,而NUTS仍然失败了。
  • 我仔细检查了github问题的修复程序是否在我正在运行的pymc3版本中。它是。

我的直觉是,这与时间^ 2和时间^ 3变量的巨大变化有关,因为我正在查看一个大的时间范围。时间^ 3从0开始并变为64,000。

到目前为止,这是我尝试过采样的内容。请注意,测试时我的样本量很小,因为它需要很长时间才能运行(如果它完成),而我只是想让它进行采样。一旦找到一个有效的,我就会增加迭代次数

with my_model:
    mu,sds,elbo = pm.variational.advi(n=500000,learning_rate=1e-1)
    print(mu['mu_b'])
    step = pm.NUTS(scaling=my_model.dict_to_array(sds)**2,
                   is_cov=True)
    my_trace = pm.sample(500, 
                         step=step, 
                         start=mu,
                         tune=100)

我也使用tune = 1000

完成了上述操作

我也尝试过Metropolis和Hamiltonian。

with my_model:
    my_trace = pm.sample(5000,step=pm.Metropolis())

with my_model:
    my_trace = pm.sample(5000,step=pm.HamiltonianMC())

问题:

  • 我对时间变量的大小和传播的直觉是否合理?
  • 有没有办法更有效地抽样方形和立方项?我已经搜索过了,但您是否也可以指点我这方面的资源,以便我可以了解更多信息?
  • Metropolis有什么问题和尺寸不匹配错误?
  • NUTS的空迹线图有什么用?通常当它停止时,跟踪直到失速工作。
  • 是否有其他方法来处理可能更容易抽样的时间?

我还没有发布玩具模型,因为没有数据就很难复制。一旦我用模拟数据复制,我会添加一个玩具模型。但实际模型如下:

with pm.Model() as my_model:
    mu_b = pm.Flat('mu_b')
    sig_b = pm.HalfCauchy('sig_b',beta=2.5)
    b_raw = pm.Normal('b_raw',mu=0,sd=1,shape=n_groups)
    b = pm.Deterministic('b',mu_b + sig_b*b_raw)

    t1 = pm.Normal('t1',mu=0,sd=100**2,shape=1)
    t2 = pm.Normal('t2',mu=0,sd=100**2,shape=1)
    t3 = pm.Normal('t3',mu=0,sd=100**2,shape=1)

    est =(b[data.group.values]* data.x.values) +\
        (t1*data.t.values)+\
        (t2*data.t2.values)+\
        (t3*data.t3.values)

    y = pm.Bernoulli('y', p=tt.nnet.sigmoid(est), observed = data.y)

突破1:大都市错误

奇怪的语法问题。 Theano似乎对具有恒定和随机效应的模型感到困惑。我在数据中创建了一个等于0的常量data['c']=0,并将其用作时间,时间^ 2和时间^ 3效果的索引,如下所示:

est =(b[data.group.values]* data.x.values) +\
            (t1[data.c.values]*data.t.values)+\
            (t2[data.c.values]*data.t2.values)+\
            (t3[data.c.values]*data.t3.values)

我不认为这是整个问题,但这是朝着正确方向迈出的一步。我敢打赌这就是为什么我的不对称规范不起作用,如果是这样,怀疑它可能会更好地采样。

更新:抽样!现在将尝试一些使采样器更容易的建议,包括使用规范suggested here。但至少它正在发挥作用!

1 个答案:

答案 0 :(得分:1)

没有数据集可以使用它很难给出明确的答案,但这是我最好的猜测:

对我来说,听到那里的三阶多项式有点出乎意料。我还没看过论文,所以我无法对它发表评论,但我认为这可能是你遇到问题的原因。即使t3的非常小的值也会对预测器产生巨大影响。为了保持这种合理性,我尝试稍微更改参数化:首先确保预测变量居中(类似于data['t'] = data['t'] - data['t'].mean(),然后定义data.t2data.t3) 。然后尝试在t2t3上设置更合理的优先级。它们应该很小,所以也许尝试像

这样的东西
t1 = pm.Normal('t1',mu=0,sd=1,shape=1)
t2 = pm.Normal('t2',mu=0,sd=1,shape=1)
t2 = t2 / 100
t3 = pm.Normal('t3',mu=0,sd=1,shape=1)
t3 = t3 / 1000

如果您想查看其他模型,可以尝试将预测变形建模为GaussianRandomWalk或高斯过程。

将pymc3更新为最新的候选版本也应该有所帮助,采样器的改进有点改进了。

更新我刚注意到您的模型中没有拦截术语。除非你有充分的理由想要添加

intercept = pm.Flat('intercept')
est = (intercept
       + b[..] * data.x
       + ...)