【问题标题】:Integration of KDE with strange behavior of from scipy.integrate.quad and the setted bandwith将 KDE 与 scipy.integrate.quad 的奇怪行为和设置的带宽集成
【发布时间】:2022-01-19 09:36:00
【问题描述】:

我正在寻找一种从绘制分布中获取 平均值(期望值)的方法,该分布用于拟合来自 scipy.stats.gaussian_kde的核密度估计>。我记得在我的统计课上,期望值只是 pdf(x) * x 从 -infinity 到 infinity 的积分:

我使用 scipy.integrate.quad 函数在我的代码中执行此任务,但我遇到了这种明显奇怪的行为(这可能与 bandwith 参数有关 来自 KDE)。

问题

import matplotlib.pyplot as plt
import numpy as np
import random
from scipy.stats import norm, gaussian_kde
from scipy.integrate import quad
from sklearn.neighbors import KernelDensity

np.random.seed(42)

# Generating sample data
test_array = np.concatenate([np.random.normal(loc=-10, scale=.8, size=100),\
np.random.normal(loc=4,scale=2.0,size=500)])


kde = gaussian_kde(test_array,bw_method=0.5)


X_range = np.arange(-16,20,0.1)

y_list = []

for X in X_range:

    pdf = lambda x : kde.evaluate([[x]])
    y_list.append(pdf(X))

y = np.array(y_list)    

_ = plt.plot(X_range,y)


# Integrate over pdf * x to obtain the mean
mean_integration_low_bw = quad(lambda x: x * pdf(x), a=-np.inf, b=np.inf)[0]

# Calculate the cdf at point of the mean
zero_int_low = quad(lambda x: pdf(x), a=-np.inf, b=mean_integration_low_bw)[0]

print("The mean after integration: {}\n".format(round(mean_integration_low_bw,4)))

print("F({}): {}".format(round(mean_integration_low_bw,4),round(zero_int_low,4)))

plt.axvline(x=mean_integration_low_bw,color ="r")
plt.show()

如果我执行此代码,我会在计算的平均值处得到积分平均值和累积分布函数的结果的奇怪行为:

第一个问题: 在我看来,它应该总是显示:F(Mean) = 0.5 还是我错了? (这只适用于对称分布吗?)

第二个问题: 更奇怪的是,积分平均值的值不会因带宽参数而改变。在我看来,如果基础分布的形状不同,平均值也应该改变。如果我将带宽设置为 5,我会得到以下图表:

如果曲线现在具有不同的形状(由于带宽更宽),为什么平均值仍然相同?

我希望这些问题的出现不仅仅是因为我对统计数据的理解有缺陷;)

【问题讨论】:

    标签: python scipy integration kernel-density quad


    【解决方案1】:

    您的初始数据在此处生成

    # Generating sample data
    test_array = np.concatenate([np.random.normal(loc=-10, scale=.8, size=100),\
                                 np.random.normal(loc=4,scale=2.0,size=500)])
    
    

    所以你有来自平均值为4 的分布的500 样本和来自平均值为-10 的分布的100 样本,你可以预测预期的平均值(500*4-10*100)/(500+100) = 1.66666...。这与您的代码给出的结果非常接近,并且与从第一个图获得的结果也非常一致。

    【讨论】:

    • 是的,我之前用 np.mean(test_array) 尝试过,并用(显然)相同的结果计算了平均值。我只是对以下事实感到困惑,即平均值不取决于不同带宽的曲线形状。获得一些统计直觉会很高兴为什么它会这样。 -> 当你整合它时,它更多的是关于它背后的数学
    • 不同的宽度(方差)将改变单个点与平均值的偏差,loc 参数定义为它们的平均值。但是当然如果你从一个样本中计算平均值,结果会有一些方差,平均值的标准差是1/sqrt(len(x))x[i]的标准差
    猜你喜欢
    • 1970-01-01
    • 2012-09-30
    • 2020-06-10
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多