【问题标题】:Custom Python Monte Carlo integration function is underestimating multi-dimensional integrals自定义 Python Monte Carlo 积分函数低估了多维积分
【发布时间】: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


【解决方案1】:

John,总体上看起来不错,但在我看来,您对预期结果的估计不正确。我认为预期的结果应该是(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 序列。我认为这也是一个有趣的想法。我在计算积分方面的经验是在 1 维或 2 维中使用正交规则,在 3 到几个(5?7?我不知道)中使用低差异序列,而 MC 不止于此。哦,我的建议是,在使用数值近似之前,要非常努力地获得准确的结果。

我很想知道你在做什么。

【讨论】:

  • 谢谢罗伯特,我假设我使用 multivariate_normal.cdf() 的方式与 (F[b] - F[a])^# 的维度相同。不幸的是,我不能使用正交规则,因为我必须使用非常高维的分布,所以运行时间会增加。我正在构建函数来处理耦合分布并计算耦合熵、交叉熵和散度。找到准确的结果很棘手,使用数值近似可以让我得到任何分布的近似结果。
猜你喜欢
  • 2021-11-08
  • 1970-01-01
  • 2020-09-03
  • 2016-06-24
  • 2016-04-05
  • 1970-01-01
  • 2021-03-11
  • 2011-07-20
  • 2017-05-16
相关资源
最近更新 更多