簡體   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