我需要创建一个自定义的蒙特卡罗集成函数,以适应使用NumPy的自定义多维分布对象。我需要它在每个维度中集成相同的值。它在单个维度上工作正常,但在多个维度上低估了,随着维度的增加,情况会变得更糟。我正在使用这个paper (方程式5)作为指导。我的体积*平均密度公式是错误的吗?我的抽样方法有误吗?我真的不知道错误是什么。
import numpy as np
from scipy.stats import multivariate_normal
# Set up distribution parameters.
dim = 3
loc = np.repeat(0., repeats=dim)
scale = np.repeat(1., repeats=dim)
# Initialize a multivariate normal distribution.
mvn = multivariate_normal(mean=loc, cov=scale)
def mc_integrator(distribution, dim, support, size=1000, seed=0):
"""
Parameters
----------
distribution : function
A probability density function.
dim : int
The number of dimensions of the distribution.
support : list
List of the low and high values of the hypercube to integrate over.
size : int, optional
Number of samples used for estimation. The default is 1000.
seed : int, optional
A random seed for reproducibility. The default is 0.
Returns
-------
float
The estimate of the integral over the hypercube.
"""
# Set the random seed.
np.random.seed(seed)
# Separate the elements of the support.
a, b = support[0], support[1]
# Calculate the volume of the hypercube.
volume = (b-a)**dim
# Generate random samples of the appropriate shape.
samples = np.random.uniform(low=a, high=b, size=(size,dim))
# Return the estimate of the integral.
return volume*np.mean(distribution(samples))
# Set the number of samples to use for estimation.
size = 10000
# Set the low and high value over each dimension of the hypercube.
support = [-2, 2]
# Print the estimate of the integral.
print(mc_integrator(mvn.pdf, dim, support, size=size))
# Print the exact value of the integral.
print(mvn.cdf(np.repeat(support[1], dim))-mvn.cdf(np.repeat(support[0], dim)))
Output: 0.8523870204938726
0.9332787601629401发布于 2021-03-02 00:44:53
约翰,总体上看起来不错,但在我看来,你没有正确计算出预期的结果。我认为预期的结果应该是(F(2) - F(-2)^3,其中F是均值为0和方差为1的高斯cdf。对于F(2) - F(-2),我得到的erf(sqrt(2))约为0.9545,然后(F(2) - F(-2))^3为0.8696,这与您的结果非常吻合。
我不知道mvn.cdf应该返回什么,但"cdf“的概念在多个维度上都有点可疑,所以也许你可以避开它。
关于多维积分,你通常会提到使用Halton序列。我认为这也是一个有趣的想法。我计算积分的经验是使用一维或二维的求积规则,使用3到几个(5? 7?)的低偏差序列。我不知道),和MC在更多。哦,还有,我的建议是,在求助于数值近似之前,要努力获得准确的结果。
我很有兴趣听听你在做什么。
https://stackoverflow.com/questions/66404952
复制相似问题