KDE 与 scipy.integrate.quad 形式的奇怪行为和指定带宽的集成
Integration of KDE with strange behavior of from scipy.integrate.quad and the setted bandwith
我一直在寻找一种方法来从绘制的分布中获取 平均值(预期值),我用它来拟合来自 [ 的核密度估计=51=]。我记得我的统计数据 class 期望值只是 pdf(x) * x 从 -infinity 到 infinity 的积分:
我在我的代码中使用了 scipy.integrate.quad 函数来完成这个任务,但是我 运行 进入这个显然 st运行ge行为(这可能与 KDE 中的 bandwith 参数 有关)。
问题
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()
如果我执行这段代码,我会得到积分均值和累积分布函数在计算均值点的结果的 st运行ge 行为:
第一个问题:
在我看来,它应该始终显示:F(Mean) = 0.5 还是我错了? (这只适用于对称分布吗?)
第二个问题:
更重要的是,积分平均值的值不会因带宽参数而改变。在我看来,如果基础分布的形状不同,均值也应该改变。如果我将带宽设置为 5,我会得到下图:
如果曲线现在具有不同的形状(由于更宽的带宽),为什么平均值仍然相同?
我希望这些问题的出现不仅仅是因为我对统计数据的理解有误 ;)
您的初始数据在这里生成
# 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)])
所以你有 500
个来自均值 4
的分布的样本和 100
个来自均值 -10
的分布的样本,你可以预测预期的平均值 (500*4-10*100)/(500+100) = 1.66666...
。这与您的代码给出的结果非常接近,并且与从第一个图获得的结果也非常一致。
我一直在寻找一种方法来从绘制的分布中获取 平均值(预期值),我用它来拟合来自 [ 的核密度估计=51=]。我记得我的统计数据 class 期望值只是 pdf(x) * x 从 -infinity 到 infinity 的积分:
我在我的代码中使用了 scipy.integrate.quad 函数来完成这个任务,但是我 运行 进入这个显然 st运行ge行为(这可能与 KDE 中的 bandwith 参数 有关)。
问题
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()
如果我执行这段代码,我会得到积分均值和累积分布函数在计算均值点的结果的 st运行ge 行为:
第一个问题: 在我看来,它应该始终显示:F(Mean) = 0.5 还是我错了? (这只适用于对称分布吗?)
第二个问题: 更重要的是,积分平均值的值不会因带宽参数而改变。在我看来,如果基础分布的形状不同,均值也应该改变。如果我将带宽设置为 5,我会得到下图:
如果曲线现在具有不同的形状(由于更宽的带宽),为什么平均值仍然相同?
我希望这些问题的出现不仅仅是因为我对统计数据的理解有误 ;)
您的初始数据在这里生成
# 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)])
所以你有 500
个来自均值 4
的分布的样本和 100
个来自均值 -10
的分布的样本,你可以预测预期的平均值 (500*4-10*100)/(500+100) = 1.66666...
。这与您的代码给出的结果非常接近,并且与从第一个图获得的结果也非常一致。