我需要计算两个函数重叠的面积。在这个简化的例子中,我使用正态分布,但我需要一个更通用的过程来适应其他函数。
请看下面的图像,了解我的意思,其中红色区域是我想要的: 这是我目前拥有的最小工作示例:
请看下面的图像,了解我的意思,其中红色区域是我想要的: 这是我目前拥有的最小工作示例:
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
# Generate random data uniformly distributed.
a = np.random.normal(1., 0.1, 1000)
b = np.random.normal(1., 0.1, 1000)
# Obtain KDE estimates foe each set of data.
xmin, xmax = -1., 2.
x_pts = np.mgrid[xmin:xmax:1000j]
# Kernels.
ker_a = stats.gaussian_kde(a)
ker_b = stats.gaussian_kde(b)
# KDEs for plotting.
kde_a = np.reshape(ker_a(x_pts).T, x_pts.shape)
kde_b = np.reshape(ker_b(x_pts).T, x_pts.shape)
# Random sample from a KDE distribution.
sample = ker_a.resample(size=1000)
# Compute the points below which to integrate.
iso = ker_b(sample)
# Filter the sample.
insample = ker_a(sample) < iso
# As per Monte Carlo, the integral is equivalent to the
# probability of drawing a point that gets through the
# filter.
integral = insample.sum() / float(insample.shape[0])
print integral
plt.xlim(0.4,1.9)
plt.plot(x_pts, kde_a)
plt.plot(x_pts, kde_b)
plt.show()
我在计算积分时使用了Monte Carlo
方法。
这种方法的问题在于,当我使用ker_b(sample)
(或ker_a(sample)
)在任一分布中评估抽样点时,我得到的值直接放在了KDE线上。因此,即使是明显重叠的分布,应该返回非常接近1的共同/重叠区域值,仍然返回较小的值(由于它们是概率密度估计,所以两个曲线的总面积均为1)。
如何修改此代码以获得预期结果?
以下是我如何应用Zhenya的答案。
# Calculate overlap between the two KDEs.
def y_pts(pt):
y_pt = min(ker_a(pt), ker_b(pt))
return y_pt
# Store overlap value.
overlap = quad(y_pts, -1., 2.)