Python 基于PyMC3的稳健贝叶斯相关

Python 基于PyMC3的稳健贝叶斯相关,python,correlation,bayesian,pymc,pymc3,Python,Correlation,Bayesian,Pymc,Pymc3,这是一个关于贝叶斯相关分析的示例,如中所述 我成功地将非稳健方法移植到PyMC3中,该方法使用多元正态分布,但我正在努力使用稳健版本,其中使用多元Student-t分布 问题是,表示方差的sigma向量最终变得太大,并且无法再计算协方差矩阵的逆。因此,相关性r的后验几乎跨越整个区间[-1;1] 完整代码在和中提供 PyMC2的相关代码为: import pymc import numpy as np from scipy.special import gammaln def analyze(d

这是一个关于贝叶斯相关分析的示例,如中所述

我成功地将非稳健方法移植到PyMC3中,该方法使用多元正态分布,但我正在努力使用稳健版本,其中使用多元Student-t分布

问题是,表示方差的
sigma
向量最终变得太大,并且无法再计算协方差矩阵的逆。因此,相关性
r
的后验几乎跨越整个区间[-1;1]

完整代码在和中提供

PyMC2的相关代码为:

import pymc
import numpy as np
from scipy.special import gammaln

def analyze(data):
    mu = pymc.Normal('mu', 0, 0.000001, size=2)
    sigma = pymc.Uniform('sigma', 0, 1000, size=2)
    rho = pymc.Uniform('r', -1, 1)

    nu = pymc.Exponential('nu',1/29., 1)
    # we model nu as an Exponential plus one
    @pymc.deterministic
    def nuplus(nu=nu):
        return nu + 1

    @pymc.deterministic
    def precision(sigma=sigma,rho=rho):
        ss1 = float(sigma[0] * sigma[0])
        ss2 = float(sigma[1] * sigma[1])
        rss = float(rho * sigma[0] * sigma[1])
        return np.linalg.inv(np.mat([[ss1, rss], [rss, ss2]]))

    # log-likelihood of multivariate t-distribution
    @pymc.stochastic(observed=True)
    def mult_t(value=data.T, mu=mu, tau=precision, nu=nuplus):
        k = float(tau.shape[0])
        res = 0
        for r in value:
            delta = r - mu
            enum1 = gammaln((nu+k)/2.) + 0.5 * np.log(np.linalg.det(tau))
            denom = (k/2.)*np.log(nu*np.pi) + gammaln(nu/2.)
            enum2 = (-(nu+k)/2.) * np.log (1 + (1/nu)*delta.dot(tau).dot(delta.T))
            result = enum1 + enum2 - denom
            res += result[0]
        return res[0,0]

    model = pymc.MCMC(locals()) 
    model.sample(50000,25000)
对于PyMC3,我可以使用内置的
MvStudentT
分布,它需要协方差矩阵而不是精度矩阵

import pymc3 as pm
import numpy as np

def mad(data, axis=None):
    return np.median(np.absolute(data - np.median(data, axis)), axis)


def covariance(sigma, rho):
    C = T.alloc(rho, 2, 2)
    C = T.fill_diagonal(C, 1.)
    S = T.diag(sigma)
    return S.dot(C).dot(S)


def analyze_robust(data):
    with pm.Model() as model:
        # priors might be adapted here to be less flat
        mu = pm.Normal('mu', mu=0., tau=0.000001, shape=2, testval=np.median(data, axis=1))
        sigma = pm.Uniform('sigma', lower=0, upper=1000, shape=2, testval=mad(data.T, axis=0))
        rho = pm.Uniform('r', lower=-1., upper=1., testval=0.5)

        cov = pm.Deterministic('cov', covariance(sigma, rho))
        nu = pm.Exponential('nu_minus_one', lam=1./29.) + 1
        mult_t = pm.MvStudentT('mult_t', nu=nu, mu=mu, Sigma=cov, observed=data.T)

    return model

非常感谢任何可能解释PyMC3下行为的提示。

我发现以下内容似乎产生了合理的结果。我基于先验知识,并用它来验证相关性。所有的工作都在这里


所以你找到你要找的东西了吗?恐怕没有。我没有进一步调查这个问题。但我确实提交了一个bug:
def mad(data, axis=None):
    return np.median(np.absolute(data - np.median(data, axis)), axis)

def covariance(sigma, rho):
    C = T.alloc(rho, 2, 2)
    C = T.fill_diagonal(C, 1.)
    S = T.diag(sigma)
    return S.dot(C).dot(S)

def analyze_robust(data):
    with pm.Model() as model:
        # priors might be adapted here to be less flat
        mu = pm.Normal('mu', mu=0., sd=100., shape=2, testval=np.median(data.T, axis=1))
        bound_sigma = pm.Bound(pm.Normal, lower=0.)
        sigma = bound_sigma('sigma', mu=0., sd=100., shape=2, testval=mad(data, axis=0))
        rho = pm.Uniform('r', lower=-1., upper=1., testval=0)
        cov = pm.Deterministic('cov', covariance(sigma, rho))
        bound_nu = pm.Bound(pm.Gamma, lower=1.)
        nu = bound_nu('nu', alpha=2, beta=10)
        mult_t = pm.MvStudentT('mult_t', nu=nu, mu=mu, Sigma=cov, observed=data)
    return model