python - 如何使用密度图识别异常值

标签 python scipy seaborn outliers density-plot

我正在尝试用我的密度图识别异常值。我目前正在使用 seaborn 库来绘制我的数据。我将如何识别异常值?我一直在考虑使用统计库实现 Z 分数,如果不能在密度图中完成,这是实现此目标的唯一方法吗?

最佳答案

核密度估计是对假设概率的估计 给定数据的密度函数 (pdf)。现在,我们有一个问题:哪些数据点应该被视为异常值。异常值是罕见的数据点,即那些点,其中 pdf极低。我们不知道 pdf,但知道它的估计值。因此,我们可以使用此估计来识别异常值。

因此,基本思想是:1) 计算所有数据点的核密度估计; 2) 找到那些估计值低于某个预定义阈值的点。 后者将是异常值。

让我们写一些代码来说明这一点。

import numpy as np
# import seaborn as sns # you probably can use seaborn to get pdf-estimation values, I would use scikit-learn package for this.
from matplotlib import pyplot as plt
from sklearn.neighbors import KernelDensity

# 100 normally distributed data points and approximately 10 outliers in the end of the array.
data = np.r_[np.random.randn(100), np.random.rand(10)*100][:, np.newaxis]

# you an use kernel='gaussian' instead
kde = KernelDensity(kernel='tophat', bandwidth=0.75).fit(data)

yvals = kde.score_samples(data)  # yvals are logs of pdf-values
yvals[np.isinf(yvals)] = np.nan # some values are -inf, set them to nan

# approx. 10 percent of smallest pdf-values: lets treat them as outliers 
outlier_inds = np.where(yvals < np.percentile(yvals, 10))[0]
print(outlier_inds)
non_outlier_inds = np.where(yvals >= np.percentile(yvals, 10))[0]
print(non_outlier_inds)

[ 33  49 100 101 102 103 105 106 107 108 109]
[  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17
  18  19  20  21  22  23  24  25  26  27  28  29  30  31  32  34  35  36
  37  38  39  40  41  42  43  44  45  46  47  48  50  51  52  53  54  55
  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72  73
  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90  91
  92  93  94  95  96  97  98  99 104]

# I applied log to data points because we need to visualize small (0,1) and large (up to 100) values on the same plot.
plt.plot(non_outlier_inds, np.log(data[non_outlier_inds]), 'ro',
         outlier_inds, np.log(data[outlier_inds]), 'bo')
plt.gca().set_xlabel('Index')
plt.gca().set_ylabel('log(data)')
plt.show()

enter image description here

关于python - 如何使用密度图识别异常值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55743251/

相关文章:

python - 在 Python 中给定坐标处将 2D 数据重新网格化到更大的 2D 网格上

python - 带有分组条形图的 Pandas 堆叠条形图

python - 如何使用 x = A 列,但颜色/色调 = B 列分类变量进行绘图

python 3.5 matplotlib 等高线图图例

python - 科学图像显示python

即使保留副本后,Python 嵌套字典也会被覆盖

python - 告诉 scipy.optimize.minimize 失败

python - 你如何解决 pyinstaller for scipy 中的 'hidden imports not found!' 警告?

python-3.x - 从 ._sparsetools 导入 csr_tocsc、csr_tobsr、csr_count_blocks、\ImportError : DLL load failed: The specified module could not be found

python - 如何在 fiddle 图中将多个 pandas 数据框绘制为单独的类别?