Python中多元正态分布的集成

时间:2018-03-22 15:52:51

标签: python numerical-integration

我正在尝试在python中集成多变量分布。为了测试它,我用双变量正态分布构建了这个玩具示例。我使用nquad()以便稍后将其扩展为两个以上的变量。这是代码:

import numpy as np
from scipy import integrate
from scipy.stats import multivariate_normal


def integrand(x0, x1, mean, cov):
    return multivariate_normal.pdf([x0, x1], mean=mean, cov=cov)

mean = np.array([100, 100])
cov = np.array([[20, 0], [0, 20]])

res, err = integrate.nquad(integrand,
                           [[-np.inf, np.inf], [-np.inf, np.inf]],
                           args=(mean, cov))

print(res)

我得到的结果是9.559199162933625e-10。显然,这是不正确的。应该(接近)1。

这里有什么问题?

2 个答案:

答案 0 :(得分:1)

scipy的nquad仅在有界矩形域上进行数值积分。你的积分收敛的事实是由于PDF的exp(-r^2) - 类型权重(请参见here的显式形式)。因此,您需要2D中的Hermite quadrature。此主题中存在Some articlesquadpy(我的项目)实现这些。

首先,您需要将积分带入包含exp(-r**2) r**2 x[0]**2 + x[1]**2的确切权重的表单中。然后你削减这个重量并将其输入quadpy的e2r2正交:

import numpy
import quadpy


def integrand(x):
    return 1 / numpy.pi * numpy.ones(x.shape[1:])


val = quadpy.e2r2.integrate(
    integrand,
    quadpy.e2r2.RabinowitzRichter(3)
    )

print(val)
1.0000000000000004

答案 1 :(得分:0)

有点题外话,但是您应该改用以下例程(速度非常快):

from scipy.stats.mvn import mvnun
import numpy as np

mean = np.array([100, 100])
cov = np.array([[20, 0], [0, 20]])
mvnun(np.array([-np.inf, -np.inf]), np.array([np.inf, np.inf]), mean, cov)

或使用multivariate_normal.cdf进行减法。