下面的MWE展示了兩種集成相同2D核心密度估計值的方法,使用stats.gaussian_kde()
函數獲得this data。使用Monte Carlo的不同積分結果vs scipy.integrate.nquad
對閾值點(x1, y1)
以下的所有(x, y)
執行積分,該閾值點定義了積分上限(積分下限爲-infinity
;請參見MWE)。
int1
函數使用簡單的蒙特卡羅方法。int2
函數使用scipy.integrate.nquad函數。
的問題是,int1
(即:蒙特卡洛方法)給出系統更大的值比int2
的積分。我不知道爲什麼會發生這種情況。
下面是對由int2
(紅色垂直線)中給出的積分結果後int1
(藍色直方圖)的200個運行得到的積分值的例子:
什麼是該差的原點在得到的積分值?
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)
。
什麼是代碼中的'x'和'y'? – Gabriel
界限,應該是'x1' /'y1',編輯\ – dfb
我這樣認爲。上面的代碼失敗:'ValueError:操作數不能與形狀(2,50000)(2,2)'一起廣播。你測試過了嗎?你可以讓它運行嗎? – Gabriel