python - 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,R=20', 'N=35,R=20'],fontsize=5)
plt.show()
解决方案
kdeplot 背后发生的事情是,内核密度与许多小的正态密度相匹配(参见此图),并且截断截止点边缘的密度溢出。
使用示例数据:
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:
这篇关于交叉验证的帖子提出了两种解决方案。我编写了@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)
推荐阅读
- java - 通过 Xpath 获取相对属性
- ruby-on-rails - 按约定设置实例变量失败
- javascript - 如何在 firebase auth 更改时更改 Vue 组件?
- java - 下面的 Java 类型转换如何工作?
- c++ - 在 Qml 中使用来自 C++ 的 url
- c# - 模型属性未传递到下一个视图
- ios - iOS 键盘扩展禁用 iPhone 上的其他应用程序
- angular - 如何在 Angular 8+ 中显示动态组件
- java - 我应该如何管理流口水中的事实插入以避免内存泄漏?
- webpack - Webpack:为什么 devserver 会生成“chunk_vendors.js”和构建“node_vendors.js”(这是我配置的名称)