检测此类异常值的方法

数据挖掘 机器学习 异常检测 离群值
2022-02-11 05:07:15

背景
我对数据科学或机器学习知之甚少(或说什么)。但我对学习很感兴趣,并认为这个问题可以通过机器学习来解决。这就是为什么我在这里发布这个,甚至不知道这是否合适。

问题 我有一些成对的(x,y)二维数据。我只有数据,不知道数据有什么样的功能特征。现在这些数据随机有一些错误的值或(我应该说)异常值。我必须在处理这些数据之前修复它们。让我们举个例子: 在此处输入图像描述

正如您所看到的,除了第 3 点之外,数据具有很好的统一特征,显然这是一个错误的点。我已经解决了这种问题。你可以看到如果我能检测到那个点,那么我可以删除它并将其与周围环境相匹配(例如用样条曲线)。现在我有很多这样的数据,每次都进行绘图以检查然后手动检测和平滑这些点真的很烦人。

现在我不知道如何处理这个问题。我试图搜索,但迷失在机器学习的巨大世界中。那么,我需要学习什么样的方法和技术,才能芳香地检测出这些点。您可以向我展示一个示例代码(最好在 python 中)来完成此类工作。谢谢。

4个回答

我最近遇到了类似的问题(从时间序列中删除异常峰值)。这就是我给你的建议:

  1. 获得平滑的趋势。您可以使用多种技术,例如各种形式的指数平滑。

  2. 找出实际趋势观察值与平滑观察值之间的差异。

  3. 标准化这种距离分布(使用 Z 分数,即sklearn's StandardScaler

  4. 替换离均值有 k 个标准差的观测值(即 0)。x 的选择可以是任意的或数据驱动的;就我而言,我选择了 k = 3(即非常保守的异常去除)。您可以使用平滑值作为替代。在您的情况下,插值可能是一个不错的选择(这取决于您的喜好)。

这将自动删除异常峰,如您显示的峰。

以下是排除异常值的简单示例:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
df = pd.DataFrame(np.random.randn(100, 1))
#print(df)

from scipy import stats
df1=df[(np.abs(stats.zscore(df)) < 2).all(axis=1)]
#print(df1)
plt.plot(df,'r', label='Outliers')
plt.plot(df1, 'b' ,label='Non-outliers')
plt.legend()

输出:

图像

描述:

  • 对于每一列,首先,它计算列z-score()中每个值相对于列均值和标准差的值。
  • np.abs(stats.zscore(df))取 Z 分数的绝对值,因为方向无关紧要,仅当它低于阈值 = 2 时。
  • all(axis=1)确保对于每一行,所有列都满足约束。
  • 最后,df[]此条件的结果用于索引数据帧。

方法 2: 您可以使用quantile()between()

x = pd.Series(np.random.normal(size=20)) # with outliers
#print(x)
o = x[x.between(x.quantile(.25), x.quantile(.75))] # without outliers
#print(x)
plt.plot(x,'r', label='Outliers')
plt.plot(o, 'b' ,label='Non-outliers')
plt.legend()

图像

我还建议您查看以下答案:answer1answer2

您所描述的那种异常值在文献中被称为“点”异常值,因为它们在其个人价值方面是异常的,不像“上下文”和“集体”异常值,它们仅在考虑其邻居(上下文)时才异常。

例如,对于点异常值检测,可以使用多种方法,具体取决于您是对离线检测还是检测感兴趣。

该存储库包含许多可用的即用型算法来检测此类异常值,适用于这两种情况。

如果您有兴趣阅读有关这些技术如何工作的更多详细信息,一些相关论文是:

https://ieeexplore.ieee.org/abstract/document/7954844

https://ieeexplore.ieee.org/abstract/document/7424283/

对于每个数据点,使用欧几里德距离计算到它的左邻 + 右邻的距离,通过比较这些距离,您应该会看到这种异常值。