python - PyMC3 将随机协方差矩阵传递给 pm.MvNormal()

标签 python theano bayesian normal-distribution pymc3

我尝试使用 PyMC3 将简单的 2D 高斯模型拟合到观察到的数据。

import numpy as np
import pymc3 as pm

n = 10000;
np.random.seed(0)
X = np.random.multivariate_normal([0,0], [[1,0],[0,1]], n);

with pm.Model() as model:
    # PRIORS
    mu = [pm.Uniform('mux', lower=-1, upper=1), 
          pm.Uniform('muy', lower=-1, upper=1)]
    cov = np.array([[pm.Uniform('a11', lower=0.1, upper=2), 0],
                    [0, pm.Uniform('a22', lower=0.1, upper=2)]])

    # LIKELIHOOD
    likelihood = pm.MvNormal('likelihood', mu=mu, cov=cov, observed=X)

with model:
    trace = pm.sample(draws=1000, chains=2, tune=1000)

虽然我可以通过将 sd 传递给 pm.Normal 来在一维中完成此操作,但在将协方差矩阵传递给 pm.MvNormal< 时遇到了一些麻烦.

我哪里出错了?

最佳答案

PyMC3 分布对象不是简单的数字对象或 numpy 数组。相反,它们是 theano 计算图中的节点,通常需要来自 pymc3.math 的操作。或theano.tensor来操纵他们。此外,将 PyMC3 对象放入 numpy 数组中是不必要的,因为它们已经是多维的。

原始模型

根据代码的意图,工作版本将类似于

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

N = 10000
np.random.seed(0)
X = np.random.multivariate_normal(np.zeros(2), np.eye(2), size=N)

with pm.Model() as model:
    # use `shape` argument to define tensor dimensions
    mu = pm.Uniform('mu', lower=-1, upper=1, shape=2)

    # diagonal values on covariance matrix
    a = pm.Uniform('a', lower=0.1, upper=2, shape=2)

    # convert vector to a 2x2 matrix with `a` on the diagonal
    cov = tt.diag(a)

    likelihood = pm.MvNormal('likelihood', mu=mu, cov=cov, observed=X)

替代模型

我认为您提供的示例只是一个传达问题的玩具。但为了以防万一,我会提到,当将协方差矩阵限制为对角矩阵时,使用多元正态(参数之间的协方差建模)的主要优点就会丢失。此外,协方差矩阵的先验理论已经很成熟,因此值得花时间考虑现有的解决方案。特别是有a PyMC3 example using the LKJ prior for covariance matrices .

以下是该示例在此上下文中的简单应用:

with pm.Model() as model_lkj:
    # use `shape` argument to define tensor dimensions
    mu = pm.Uniform('mu', lower=-1, upper=1, shape=2)

    # LKJ prior for covariance matrix (see example)
    packed_L = pm.LKJCholeskyCov('packed_L', n=2,
                                 eta=2., sd_dist=pm.HalfCauchy.dist(2.5))
    # convert to (2,2)
    L = pm.expand_packed_triangular(2, packed_L)

    likelihood = pm.MvNormal('likelihood', mu=mu, chol=L, observed=X)

关于python - PyMC3 将随机协方差矩阵传递给 pm.MvNormal(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53222664/

相关文章:

python - 如何使用 python 读取和打印整个 .txt 文件?

python - 为什么 Pylint 不喜欢内置函数?

python - pandas 根据各个部分将字符串拆分为多列

neural-network - 神经网络回归预测的截止

python - 无法标记多行 sns.catplot()

nlp - 在 Keras 中实现 word2vec

python - Theano 损失函数中的对数行列式

math - 是否有用于从计数数据中学习狄利克雷先验的 R 包

machine-learning - 如何选择线性回归的高斯基函数超参数?

python - 我可以在 sklearn 贝叶斯分类器中设置先验特征吗?