【发布时间】:2016-06-24 11:21:56
【问题描述】:
下面的 MWE 显示了集成相同 2D 内核密度估计的两种方法,使用 stats.gaussian_kde() 函数为 this data 获得。
对低于阈值点(x1, y1) 的所有(x, y) 执行积分,该阈值定义了积分上限(积分下限为-infinity;请参阅MWE)。
-
int1函数使用简单的蒙特卡罗方法。 -
int2函数使用scipy.integrate.nquad 函数。
问题在于int1(即:蒙特卡洛方法)系统地给出了比int2 更大的积分值。我不知道为什么会这样。
下面是int1(蓝色直方图)200 次运行后获得的积分值与int2(红色垂直线)给出的积分结果的示例:
产生的积分值差异的根源是什么?
MWE
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from scipy import integrate
def int1(kernel, x1, y1):
# Compute the point below which to integrate
iso = kernel((x1, y1))
# Sample KDE distribution
sample = kernel.resample(size=50000)
# Filter the sample
insample = kernel(sample) < iso
# The integral is equivalent to the probability of drawing a
# point that gets through the filter
integral = insample.sum() / float(insample.shape[0])
return integral
def int2(kernel, x1, y1):
def f_kde(x, y):
return kernel((x, y))
# 2D integration in: (-inf, x1), (-inf, y1).
integral = integrate.nquad(f_kde, [[-np.inf, x1], [-np.inf, y1]])
return integral
# Obtain data from file.
data = np.loadtxt('data.dat', unpack=True)
# Perform a kernel density estimate (KDE) on the data
kernel = stats.gaussian_kde(data)
# Define the threshold point that determines the integration limits.
x1, y1 = 2.5, 1.5
i2 = int2(kernel, x1, y1)
print i2
int1_vals = []
for _ in range(200):
i = int1(kernel, x1, y1)
int1_vals.append(i)
print i
添加
请注意,此问题源自this answer。起初我并没有注意到答案在使用的积分限制上有误,这就解释了为什么int1 和int2 之间的结果不同。
int1 正在整合到域 f(x,y)<f(x1,y1)(其中 f 是内核密度估计),而 int2 整合到域 (x,y)<(x1,y1)。
【问题讨论】:
标签: python scipy montecarlo integral