python中KDE的光滑逼近
我试图在我的KDE的绘图上只获得x轴上的非负值。我知道我可以限制x轴的值,但我不想这样。有没有办法平滑地近似KDE,这样就没有非负值?我所有的数据都是非负的,但我没有太多的采样点(最多500个,我无法获得更多)。我也尝试过调整带宽,但看起来不太好python中KDE的光滑逼近,python,seaborn,statsmodels,kde,scipy.stats,Python,Seaborn,Statsmodels,Kde,Scipy.stats,我试图在我的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=
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
您可以为以下两种情况绘制它:
fig,ax = plt.subplots()
for i in data.columns:
_x,_y = trunc_dens(data[i])
ax.plot(_x,_y)
这是否回答了您的问题?Seaborn的kdeplot有一个
clip=
参数,可能很有用。请注意,获取更多数据只会有一点帮助,因为高斯kde只假设平滑分布,没有截止线。
fig,ax = plt.subplots()
for i in data.columns:
_x,_y = trunc_dens(data[i])
ax.plot(_x,_y)