如何解决python中KDE的平滑逼近
我试图为我的KDE在图的x轴上仅获取非负值。我知道我可以限制x轴值,但我不希望那样。有没有办法平滑地估计KDE使得没有非负值?我的所有数据均为非负数,但我没有很多采样点(最大500个样本点,我无法获得更多)。我也尝试过调整带宽,但看起来不太好。
for i in range(len(B)):
ax = sns.kdeplot(data[i],shade=True)
ax.set_xlabel('Maimum detection time')
ax.legend(['N=25,R=20','N=30,'N=35,R=20'],fontsize=5)
plt.show()
解决方法
kdeplot后面发生的事情是,内核密度拟合了许多小的正常密度(请参见this illustration),并且截断边界最边缘的密度溢出了。
使用示例数据:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
import pandas as pd
import statsmodels.api as sm
from scipy.stats import norm
np.random.seed(999)
data = pd.DataFrame({'a':np.random.exponential(0.3,100),'b':np.random.exponential(0.5,100)})
如果您使用clip=
,它不会使评估停止为负值:
for i in data.columns:
ax = sns.kdeplot(data[i],shade=True,gridsize=200)
如果添加cut=0
,它将看起来很奇怪。如您所指出的,您可以将其截断为0:
此post on cross-validated中提出了两种解决方案。我编写了@whuber提供的R代码的python实现:
def trunc_dens(x):
kde = sm.nonparametric.KDEUnivariate(x)
kde.fit()
h = kde.bw
w = 1/(1-norm.cdf(0,loc=x,scale=h))
d = sm.nonparametric.KDEUnivariate(x)
d = d.fit(bw=h,weights=w / len(x),fft=False)
d_support = d.support
d_dens = d.density
d_dens[d_support<0] = 0
return d_support,d_dens
我们可以检查一下data['a']
的外观:
kde = sm.nonparametric.KDEUnivariate(data['a'])
kde.fit()
plt.plot(kde.support,kde.density)
_x,_y = trunc_dens(data['a'])
plt.plot(_x,_y)
您可以同时绘制两个图:
fig,ax = plt.subplots()
for i in data.columns:
_x,_y = trunc_dens(data[i])
ax.plot(_x,_y)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。