繁体   English   中英

如何使用 Python 中的 Kernel 密度估计生成 CDF?

[英]How can I generate a CDF using Kernel Density Estimation in Python?

我遇到的几种方法可以进行 kernel 密度估计,这将为数据样本提供 PDF:

  • KDEpy
  • sklearn.neighbors.KernelDensity
  • scipy.stats.gaussian_kde

使用上述任何一种方法,我都可以生成 PDF 但是我想知道如何获得我正在生成的 PDF 的 CDF。 在数学上,我知道您可以在 PDF 上集成以获得 CDF,但问题是这些方法仅提供 x 和 y 点,而不是 function 来集成。

我想知道如何将提供的数据转换为 CDF plot 或者找到 PDF function 以获取 CDF 数据然后集成。 或者使用另一种方法,其中 output 是 CDF 而不是 PDF。

MCVE

让我们创建一些虚拟数据来进行讨论:

import numpy as np
from scipy import stats
import matplotlib.pyplot as plt

np.random.seed(123)
data = stats.norm(loc=0, scale=1).rvs(10**4)

这是scipy.stats package 的基本思想。

高斯 KDE

我们可以使用gaussian_kde等专用工具估计 KDE:

kde = stats.gaussian_kde(data)

它公开了一个PDF function 以在每个x处进行评估,但缺少CDF

连续变量

scipy.stats package 还公开了一个通用的 class rv_continous来继承。 如文档中所述:

可以通过对rv_continuous class 进行子类化并至少重新定义_pdf_cdf方法(标准化为位置 0 和比例尺 1)来定义新的随机变量。

所以我们可以使用这个有目的的逻辑来填补空白。 没有任何性能考虑,它归结为:

class KDEDist(stats.rv_continuous):
    
    def __init__(self, kde, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._kde = kde
    
    def _pdf(self, x):
        return self._kde.pdf(x)

然后我们使用我们的实验性 KDE 创建底层 object。

X = KDEDist(kde)

现在你可以自然地 - 至少在 API 调用方面 - 评估PDFCDF

fig, axe = plt.subplots()
axe.hist(data, density=1)
axe.plot(x, X.pdf(x))
axe.plot(x, X.cdf(x))

它返回:

在此处输入图像描述

性能注意事项

请注意,这种方法可以回答您的问题,但效果不佳。 KDE 计算很昂贵,因为 kernel 跨越了整个空间。 没有截止计算是基于数据集的所有观察。

更改 window function 可以显着提高性能。 例如:三角形 window 将在整个数据集上具有固定跨度并减少计算 w.r.t。 数据集范围和大小。

实施注意事项

阅读文档,似乎rv_continuous最初旨在实现具有分析定义的新连续变量。

无论如何,如果未实现(覆盖)底层方法,class 为其他统计数据提供自动解析/集成。

选择此方法时,如果您希望使其更具性能和鲁棒性(数值稳定性),则由您来实现缺失的逻辑。

直方图而不是 KDE

如果您可以放宽KDE需求并通过直方图分布满足,那么您可以依赖rv_histogram ,它基本上基于分箱分布执行相同的操作:

hist = np.histogram(data, bins=100)
hist_dist = stats.rv_histogram(hist)

返回:

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM