gpt4 book ai didi

Python:正值的核密度估计

转载 作者:行者123 更新时间:2023-12-01 01:37:35 24 4
gpt4 key购买 nike

我想获得正数据点的核密度估计。使用 Python Scipy Stats 包,我想出了以下代码。

def get_pdf(data):
a = np.array(data)
ag = st.gaussian_kde(a)
x = np.linspace(0, max(data), max(data))
y = ag(x)
return x, y

这对于大多数数据集都适用,但对于“全正”数据点会给出错误的结果。为了确保其正常工作,我使用数值积分来计算该曲线下的面积。

def trapezoidal_2(ag, a, b, n):
h = np.float(b - a) / n
s = 0.0
s += ag(a)[0]/2.0
for i in range(1, n):
s += ag(a + i*h)[0]
s += ag(b)[0]/2.0
return s * h

由于数据分布在区域 (0, int(max(data))) 中,因此在执行以下行时,我们应该得到一个接近 1 的值。

b = 1
data = st.pareto.rvs(b, size=10000)
data = list(data)

a = np.array(data)
ag = st.gaussian_kde(a)
trapezoidal_2(ag, 0, int(max(data)), int(max(data))*2)

但当我测试时它给出的值接近 0.5。

但是当我从 -100 积分到 max(data) 时,它提供的值接近 1。

trapezoidal_2(ag, -100, int(max(data)), int(max(data))*2+200)

原因是,ag (KDE) 被定义为小于 0 的值,即使原始数据集仅包含正值。

那么如何获得仅考虑正值的核密度估计,使得 (o, max(data)) 区域中曲线下的面积接近 1?

最佳答案

在执行核密度估计时,带宽的选择非常重要。我认为斯科特规则和西尔弗曼规则对于类似于高斯的分布非常有效。然而,它们对于帕累托分布来说效果不佳。

引自 doc :

Bandwidth selection strongly influences the estimate obtained from the KDE (much more so than the actual shape of the kernel). Bandwidth selection can be done by a "rule of thumb", by cross-validation, by "plug-in methods" or by other means; see [3], [4] for reviews. gaussian_kde uses a rule of thumb, the default is Scott's Rule.

尝试使用不同的带宽值,例如:

import numpy as np
import matplotlib.pyplot as plt

from scipy import stats

b = 1

sample = stats.pareto.rvs(b, size=3000)
kde_sample_scott = stats.gaussian_kde(sample, bw_method='scott')
kde_sample_scalar = stats.gaussian_kde(sample, bw_method=1e-3)


# Compute the integrale:
print('integrale scott:', kde_sample_scott.integrate_box_1d(0, np.inf))
print('integrale scalar:', kde_sample_scalar.integrate_box_1d(0, np.inf))

# Graph:
x_span = np.logspace(-2, 1, 550)
plt.plot(x_span, stats.pareto.pdf(x_span, b), label='theoretical pdf')
plt.plot(x_span, kde_sample_scott(x_span), label="estimated pdf 'scott'")
plt.plot(x_span, kde_sample_scalar(x_span), label="estimated pdf 'scalar'")
plt.xlabel('X'); plt.legend();

给出:

integrale scott: 0.5572130540733236
integrale scalar: 0.9999999999968957

和:

pareto and kde

我们发现使用 Scott 方法的 kde 是错误的。

关于Python:正值的核密度估计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52245897/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com