【发布时间】:2021-05-29 23:07:43
【问题描述】:
我需要创建一个自定义的 Monte Carlo 积分函数,以适应使用 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
【问题讨论】:
-
10000 个样本对于 MCI 来说非常低。
-
1,000,000 个样本只有 0.8694640813906446,所以仍然被低估了。它似乎总是被低估,并且 MC 有时也应该高于真实值。当您增加分布的维度时,低估问题会变得更糟,因此它必须与我处理多个维度的方式有关。编辑:一旦我让天真的 MC 集成工作,我将添加使用 Halton 序列生成样本的选项,这将减少所需的样本数量。
标签: numpy probability numerical-methods montecarlo numerical-integration