gaussian_kde
中的scipy.stats
函数有一个函数evaluate
,可以返回输入点的PDF值。我正在尝试使用gaussian_kde
来估算逆CDF。动机是生成一些输入数据的蒙特卡洛实现,其统计分布使用KDE进行数值估计。是否有一个绑定到gaussian_kde
的方法用于此目的?
以下示例显示了高斯分布情况下该如何工作。首先,我展示如何进行PDF计算以设置我想要实现的特定API:
import numpy as np
from scipy.stats import norm, gaussian_kde
npts_kde = int(5e3)
n = np.random.normal(loc=0, scale=1, size=npts_kde)
kde = gaussian_kde(n)
npts_sample = int(1e3)
x = np.linspace(-3, 3, npts_sample)
kde_pdf = kde.evaluate(x)
norm_pdf = norm.pdf(x)
有一种类似的简单方法来计算逆CDF吗? norm
函数有一个非常方便的isf
函数,可以完成这个:
cdf_value = np.sort(np.random.rand(npts_sample))
cdf_inv = norm.isf(1 - cdf_value)
kde_gaussian
是否存在此功能?或者从已经实现的方法构建这样的函数是否直接?
答案 0 :(得分:1)
方法integrate_box_1d
可以用来计算CDF,但它没有矢量化;你需要循环点。如果内存不是问题,以向量形式重写其source code(实质上只是调用special.ndtr
)可能会加快速度。
from scipy.special import ndtr
stdev = np.sqrt(kde.covariance)[0, 0]
pde_cdf = ndtr(np.subtract.outer(x, n)).mean(axis=1)
plot(x, pde_cdf)
反函数的图是plot(pde_cdf, x)
。如果目标是计算特定点的反函数,请考虑使用the inverse of interpolating spline,插入CDF的计算值。
答案 1 :(得分:1)
您可以使用一些python技巧来快速且有效地估计CDF(基于this answer):
from scipy.special import ndtr
cdf = tuple(ndtr(np.ravel(item - kde.dataset) / kde.factor).mean()
for item in x)
它的工作速度与this answer一样快,但是具有线性(len(kde.dataset)
)的空间复杂度,而不是二次(实际上是len(kde.dataset) * len(x)
)的空间。
接下来要做的就是使用逆逼近,例如从statsmodels开始。