Python 使用PYMC3求和RVs

Python 使用PYMC3求和RVs,python,bayesian,pymc3,Python,Bayesian,Pymc3,我试图从图像中实现模型。我是PyMC3新手,不知道如何正确构造模型。我的尝试如下: #示例数据 logprem=np.数组([8.66768002,8.49862181,8.60410456,8.54966038,8.55910259, 8.56216656, 8.51559191, 8.60630237, 8.56140145, 8.50956416]) 以Model()作为模型: logelr=Normal('logelr',-0.4,np.sqrt(10),形状=10) α0 = 0 β9

我试图从图像中实现模型。我是PyMC3新手,不知道如何正确构造模型。我的尝试如下:

#示例数据
logprem=np.数组([8.66768002,8.49862181,8.60410456,8.54966038,8.55910259,
8.56216656, 8.51559191, 8.60630237, 8.56140145, 8.50956416])
以Model()作为模型:
logelr=Normal('logelr',-0.4,np.sqrt(10),形状=10)
α0 = 0
β9 = 0
α=正常(‘α’,0,σ=np.sqrt(10),形状=9)
β=正常(‘β’,0,σ=np.sqrt(10),形状=9)
a=均匀('a',0,1,形状=10)
σ0=a[0]+a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]
σ1=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]
σ2=a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]
σ3=a[3]+a[4]+a[5]+a[6]+a[7]+a[8]+a[9]
σ4=a[4]+a[5]+a[6]+a[7]+a[8]+a[9]
σ5=a[5]+a[6]+a[7]+a[8]+a[9]
σ6=a[6]+a[7]+a[8]+a[9]
σ7=a[7]+a[8]+a[9]
σ8=a[8]+a[9]
σ9=a[9]
σ = [σ0, σ1, σ2, σ3, σ4, σ5, σ6, σ7, σ8, σ9]
对于范围(10)内的w:
对于范围(10)内的d:
如果w==0:
如果d==9:
μ=logprem[w]+logelr+α0+β9
其他:
μ=logprem[w]+logelr+α0+β[d]
其他:
如果d==9:
μ=logprem[w]+logelr+α[w-1]+β9
其他:
μ=logprem[w]+logelr+α[w-1]+β[d]
C=对数正态('C',μ,σ[d])
运行此命令会导致类型错误

TypeError:对于计算测试值,一个输入测试值没有请求的类型。
将测试值转换为该变量类型时出错:
尺寸数量错误:应为0,得到1,形状为(10,)。
如何用正确的形状定义C


C的正确形状是
(W,D)
,由于这一切的基础是张量对象上的Theano计算图,因此最好避免循环,并将自己限制为。下面是一个这样的实现:

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

D = 10
W = 10

# begin with (W,1) vector, then broadcast to (W,D)
logprem = tt._shared(
    np.array(
        [[8.66768002, 8.49862181, 8.60410456, 8.54966038, 8.55910259,
          8.56216656, 8.51559191, 8.60630237, 8.56140145, 8.50956416]]) \
      .T \
      .repeat(D, axis=1))

with pm.Model() as model:
    logelr = pm.Normal('logelr', -0.4, np.sqrt(10))

    # col vector
    alpha = pm.Normal("alpha", 0, sigma=np.sqrt(10), shape=(W-1,1))

    # row vector
    beta = pm.Normal("beta", 0, sigma=np.sqrt(10), shape=(1,D-1))

    # prepend zero and broadcast to (W,D)
    alpha_aug = tt.concatenate([tt.zeros((1,1)), alpha], axis=0).repeat(D, axis=1)

    # append zero and broadcast to (W,D)
    beta_aug = tt.concatenate([beta, tt.zeros((1,1))], axis=1).repeat(W, axis=0)

    # technically the indices will be reversed
    # e.g., a[0], a[9] here correspond to a_10, a_1 in the paper, resp.
    a = pm.Uniform('a', 0, 1, shape=D)

    # Note: the [::-1] sorts it in the order specified 
    # such that (sigma_0 > sigma_1 > ... )
    sigma = pm.Deterministic('sigma', tt.extra_ops.cumsum(a)[::-1].reshape((1,D)))

    # now everything here has shape (W,D) or is scalar (logelr)
    mu = logprem + logelr + alpha_aug + beta_aug

    # sigma will be broadcast automatically
    C = pm.Lognormal('C', mu=mu, sigma=sigma, shape=(W,D))
关键在于

  • alpha
    beta
    前面加上零,使一切都保持张量形式
  • 使用
    tt.extra_ops.cumsum
    方法简洁地表达步骤5
  • 获取步骤6中的所有术语,使其具有形状(W,D)
如果可以使用加法运算符在
alpha
beta
向量之间执行外积(例如,在R中,
outer
函数允许任意运算),则这可以进一步简化,但我在
theano.tensor
下找不到这样的方法

使用NUTS并不能很好地进行示例,但一旦您实际观察到要插入的
C
值,可能会更好

with model:
    # using lower target_accept and tuning throws divergences
    trace = pm.sample(tune=5000, draws=2000, target_accept=0.99)

pm.summary(trace, var_names=['alpha', 'beta', 'a', 'sigma'])
由于这只是先前的采样,唯一有趣的是转换变量的分布
sigma

pm.plot_forest(trace, var_names=['sigma'])


你能看到哪一个符合
sigma_{d}>sigma_{d+1}

谢谢你的回答。您的评论对理解如何使用PyMC3库非常有帮助。我希望有一种比我的例子更像蟒蛇的方式来写累积和,所以感谢你的加入。我已经发布了一篇关于传递2d观察结果的正确方式的后续文章。