Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:正值的核密度估计_Python_Scipy_Statistics - Fatal编程技术网

Python:正值的核密度估计

Python:正值的核密度估计,python,scipy,statistics,Python,Scipy,Statistics,我想得到正数据点的核密度估计。使用pythonscipystats包,我得到了以下代码 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 这对大多数数据集都非常有效,但对于“所有正”数据点,它给出了错误的结果。为了确保这是正确的,我使用数值积分来计算这条曲线

我想得到正数据点的核密度估计。使用pythonscipystats包,我得到了以下代码

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

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

引自:

带宽选择强烈影响从中获得的估计 KDE(远远超过内核的实际形状)。带宽选择 可以通过“经验法则”、交叉验证和“插件”来实现 方法”或其他方式;查看[3],[4]了解评论<代码>高斯_kde 使用经验法则,默认为Scott法则

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

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
以及:

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