Seaborn KDEPlot - 数据变化不够?

iay*_*ork 4 python kernel-density seaborn

我有一个包含 ~900 行的数据框;我正在尝试为某些列绘制 KDEplots。在某些列中,大多数值是相同的最小值。当我包含太多最小值时,KDEPlot 会突然停止显示最小值。例如,以下包括 600 个值,其中 450 个是最小值,并且绘图看起来不错:

y = df.sort_values(by='col1', ascending=False)['col1'].values[:600]
sb.kdeplot(y)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

但是包括 451 个最小值给出了非常不同的输出:

y = df.sort_values(by='col1', ascending=False)['col1'].values[:601]
sb.kdeplot(y)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

最终,我想绘制不同列的双变量 KDEPlots,但我想先了解这一点。

Joh*_*anC 7

问题是为kde的“带宽”选择的默认算法。默认方法'scott',当有许多相等的值时,这不是很有帮助。

带宽是位于每个采样点并相加的高斯线的宽度。较低的带宽更接近数据,较高的带宽使一切变得平滑。甜蜜点在中间的某个地方。在这种情况下bw=0.3可能是一个不错的选择。为了比较不同的kde,建议每次选择完全相同的带宽。

下面是一些示例代码,以示区别bw='scott'bw=0.3。示例数据是来自标准正态分布的 150 个值以及 400、450 或 500 个固定值。

import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns; sns.set()

fig, axs = plt.subplots(nrows=2, ncols=3, figsize=(10,5), gridspec_kw={'hspace':0.3})

for i, bw in enumerate(['scott', 0.3]):
    for j, num_same in enumerate([400, 450, 500]):
        y = np.concatenate([np.random.normal(0, 1, 150), np.repeat(-3, num_same)])
        sns.kdeplot(y, bw=bw, ax=axs[i, j])
        axs[i, j].set_title(f'bw:{bw}; fixed values:{num_same}')
plt.show()
Run Code Online (Sandbox Code Playgroud)

第三个图警告不能使用 Scott 建议的带宽绘制 kde。

示例图

PS:正如@mwascom 在评论中提到的,在这种情况下scipy.statsmodels.nonparametric.kde使用 (not scipy.stats.gaussian_kde)。默认是"scott" - 1.059 * A * nobs ** (-1/5.), where A is min(std(X),IQR/1.34). 该min()澄清的行为突然改变。IQR“四分位距”即第 75 个和第 25 个百分位数之间的差值

编辑:既然Seaborn 0.11,statsmodel后台已被删除,所以KDE的通过仅计算scipy.stats.gaussian_kde

  • 只是在这里添加一些背景信息:我认为对此最令人惊讶的方面(附加数据点的突然变化)的解释是 statsmodels 在计算 Scott 因子时使用 `min(iqr, sd)` ,并且这些传播度量可以是对于具有大量重复观察的数据来说,情况就完全不同了。 (2认同)
  • 一般来说,高斯 KDE 适用于平滑连续数据。您可以尝试过滤掉异常值并将其计数单独绘制为条形图(或小饼图)。 (2认同)