数据分析--异常值处理

参考资料:

机器学习中的异常值检测和处理
学会五种常用异常值检测方法,亡羊补牢不如积谷防饥 - 机器之心的文章 - 知乎

1 什么是异常值?

  1. 模型通常是对整体样本数据结构的一种表达方式,这种表达方式通常抓住的是整体样本一般性的性质,而那些在这些性质上表现完全与整体样本不一致的点,我们就称其为异常点

  2. 异常点在某些场景下极为重要,如疾病预测,通常健康人的身体指标在某些维度上是相似,如果一个人的身体指标出现了异常,那么他的身体情况在某些方面肯定发生了改变,当然这种改变并不一定是由疾病引起(通常被称为噪音点),但异常的发生和检测是疾病预测一个重要起始点。相似的场景也可以应用到信用欺诈,网络攻击等等。

2 异常值的检测方法

1. 简单统计

  • 直接观察整体数据,使用pandas.describe()观察数据的统计描述(统计数据应当为连续性)
  • 简单使用散点图,从图中即可看出

在这里插入图片描述

2. 3 σ \sigma σ原则

前提条件:数据分布需要服从正态分布或者近似正态分布
这个是根据正态分布的性质而得出的方法

在这里插入图片描述

一个正态分布的横轴区间 ( μ − 3 σ , μ + 3 σ ) (\mu-3\sigma,\mu+3\sigma) μ3σ,μ+3σ)内的面积为99.730020%。
若是不服从正态分布,可以使用原理 n n n倍标准差来描述,具体 n n n由应用场景确定

算法实现


import numpy as np
import matplotlib.pyplot as plt
seed(1)
anomalies = []

# multiply and add by random numbers to get some real values
data = np.random.randn(50000)  * 20 + 20

# Function to Detection Outlier on one-dimentional datasets.
def find_anomalies(random_data):
    # Set upper and lower limit to 3 standard deviation
    random_data_std = std(random_data)
    random_data_mean = mean(random_data)
    anomaly_cut_off = random_data_std * 3

    lower_limit  = random_data_mean - anomaly_cut_off 
    upper_limit = random_data_mean + anomaly_cut_off
    print(lower_limit)
    # Generate outliers
    for outlier in random_data:
        if outlier > upper_limit or outlier < lower_limit:
            anomalies.append(outlier)
    return anomalies

find_anomalies(data)

3.箱型图

使用箱型图的四方位居(IQR)对异常进行检测,也叫Tukey`s test

举例:

#计算df中某列的25%分位,下分位
Q1 =  np.percentile(df[col], 25)
#计算df中某列的75%分位,上分位
Q2 = np.percentile(df[col], 75)
IQR = Q2-Q1

一般使用IQR的 1.5 1.5 1.5倍为标准:

  • 值大于上四分位+1.5*IQR为异常值
  • 值小于"下四分位-1.5*IQR"为异常值


在这里插入图片描述

举例:

这只是举例检测异常的一个函数

def detect_outliers(df,n,features):
    '''
        features:检测这个特征集然后检测特征集中某个特征是否含有异常值,将含有异常值的index记录下来
        若是某个index中(即某行)含有的异常值超过n个,就将其加入到outlier_indices

    '''
    outlier_indices=[]
    
    for col in features:
        # 1st quartile(25%)
        Q1 = np.percentile(df[col],25)
        #3rd quartile (75%)
        Q3 = np.percentile(df[col],75)
        # 四分位
        IQR = Q3-Q1
        
        #异常值范围
        outlier_step = 1.5*IQR
        
        outlier_list_col = df[(df[col]<Q1-outlier_step)|(df[col]>Q3 + outlier_step)].index
        
        outlier_indices.extend(outlier_list_col)
        
    outlier_indices = Counter(outlier_indices)
    multiple_outliers = list(k for k,v in outlier_indices.items() if v > n)
    
    return multiple_outliers

使用seaborn中的boxplot或者boxenplot画图
图上的菱形黑点就是异常值

在这里插入图片描述

4. 基于模型检测

这种方法一般会构建一个概率分布模型,并计算对象符合该模型的概率,把具有低概率的对象视为异常点。

  • 如果模型是簇的集合,则异常是不显著属于任何簇的对象;
  • 如果模型是回归时,异常是相对远离预测值的对象。

离群点的概率定义:离群点是一个对象,关于数据的概率分布模型,它具有低概率。这种情况的前提必须知道数据集服从什么分布,如果估计错误就造成了重尾分布。

比如特征工程中的RobustScaler方法,在做数据特征值缩放的时候,它会利用数据特征的分位数分布,将数据根据分位数划分为多段,只取中间段来做缩放,比如只取25%分位数到75%分位数的数据做缩放。这样减小了异常数据的影响。

优缺点

  • (1)有坚实的统计学理论基础,当存在充分的数据和所用的检验类型的知识时,这些检验可能非常有效;
  • (2)对于多元数据,可用的选择少一些,并且对于高维数据,这些检测可能性很差。

5.基于近邻度的离群点检测

统计方法是利用数据的分布来观察异常值,一些方法甚至需要一些分布条件,而在实际中数据的分布很难达到一些假设条件,而在实际中数据的分布很难达到一些假设条件,在使用上有一定的局限性

确定数据集的有意义的邻近性度量比确定它的统计分布更容易。这种方法比统计学方法更一般、更容易使用,因为一个对象的离群点得分由到它的 k k k-最近邻(KNN)的距离给定。

需要注意的是:离群点得分对 k k k取值高度敏感。如果k太小,则少量的邻近离群点可能导致较低的离群点得分;如果 K K K太大,则点数少于 k k k的簇中所有的对象可能都成了离群点。为了使该方案对于 k k k的选取更具有鲁棒性,可以使用 k k k个最近邻的平均距离。

优缺点

  1. 简单;
  2. 缺点:基于邻近度的方法需要 O ( m 2 ) O(m^2) O(m2)时间,大数据集不适用;
  3. 该方法对参数的选择也是敏感的;
  4. 不能处理具有不同密度区域的数据集,因为它使用全局阈值,不能考虑这种密度的变化。

6. 基于密度的异常检测

从基于密度的观点来说,离群点是在低密度区的对象。、

基于密度的离群点检测与基于邻近度的离群点检测密切相关,因为密度通常用邻进度定义。

  • 一种常用的定义密度的方法是,定义密度为到k个最近邻的平均距离的倒数。如果该距离小,则密度高,反之亦然。
  • 另一种密度定义是使用DBSCAN聚类算法使用的密度定义,即一个对象周围的密度等于该对象指定距离 d d d内对象的个数。

优缺点

  1. 给出了对象是离群点的定量度量,并且即使数据具有不同的区域也能够很好的处理;
  2. 与基于距离的方法一样,这些方法必然具有 O ( m 2 ) O(m_2) O(m2)的时间复杂度。对于低维数据使用特定的数据结构可以达到 O ( m log ⁡ m ) O(m\log{m}) O(mlogm)
  3. 参数选择是困难的。虽然LOF算法通过观察不同的k值,然后取得最大离群点得分来处理该问题,但是,仍然需要选择这些值的上下界。

7.基于聚类的异常检测

一个对象是基于聚类的离群点,如果该对象不属于任何簇,那么该对象属于离群点

DBScan 是一种用于把数据聚成组的聚类算法。它同样也被用于单维或多维数据的基于密度的异常检测。其它聚类算法比如 k 均值和层次聚类也可用于检测离群点。

核心点:在定义DBScan任务的超参数,第一个超参数是min_samples。这只是形成簇所需的最小核心点数量。第二个重要的超参数是eps。eps可以视为同一个簇中两个样本之间的最大距离

边界点与核心点位于同一个簇中,但前者距离簇的中心要远得多
在这里插入图片描述

离群点对初始聚类的影响:

如果通过聚类检测离群点,则由于离群点影响聚类,存在一个问题:结构是否有效。
这也是k-means算法的缺点,对离群点敏感。
为了处理该问题,可以使用如下方法:对象聚类,删除离群点,对象再次聚类(这个不能保证产生最优结果)。

优缺点

  1. 基于线性和接近线性复杂度(k均值)的聚类技术来发现离群点可能是高度有效的;
  2. 簇的定义通常是离群点的补,因此可能同时发现簇和离群点;
  3. 产生的离群点集和它们的得分可能非常依赖所用的簇的个数和数据中离群点的存在性;
  4. 聚类算法产生的簇的质量对该算法产生的离群点的质量影响非常大。

8.专门的离群点检测

其实以上说到聚类方法的本意是是无监督分类,并不是为了寻找离群点的,只是恰好它的功能可以实现离群点的检测,算是一个衍生的功能。

除了以上提及的方法,还有两个专门用于检测异常点的方法比较常用:One Class SVM和Isolation Forest,详细内容不进行深入研究。

9. 孤立森林

https://blog.csdn.net/extremebingo/article/details/80108247

     ~~~~     孤立森林是一种无监督学习算法,属于组合决策树家族。这种方法和以上所有方法都不同。之前的所有方法都在试图寻找数据的常规区域,然后将任何在此定义区域之外的点都视为离群点或异常值。

     ~~~~     这种方法的工作方式不同。它明确地隔离异常值, 而不是通过给每个数据点分配一个分数来分析和构造正常的点和区域。它利用了这样一个事实:异常值只是少数,并且它们具有与正常实例非常不同的属性值。

     ~~~~     该算法适用于高维数据集,并且被证明是一种非常有效的异常检测方法。由于本文关注的是实现,而不是理论,因此作者不打算进一步讨论算法的工作原理。但是,周志华合著的论文《Isolation Forest》涵盖了其工作方式的全部细节。

10.Robust Random Cut Forest

Github地址

Random Cut Forest (RCF) 算法是亚马逊用于异常检测的无监督算法。它也通过关联异常分数来工作。较低的分数值表示数据点点是正常的,较高的分数值则表示数据中存在异常。

「低」和「高」的定义取决于应用,但一般实践表明,超过平均分三个标准差的分数被认为是异常的。
算法的细节可以在论文《Robust Random Cut Forest Based Anomaly Detection On Streams》里找到。

这个算法的优点在于它可以处理非常高维的数据。它还可以处理实时流数据(内置 AWS Kinesis Analytics)和离线数据

作者在下面的视频中更详细地解释了这个概念https://youtu.be/yx1vf3uapX8

本文给出了与孤立森林相比的一些性能基准。本文的研究结果表明,RCF 比孤立森林更准确、更快速。
在这里插入图片描述

3 异常值的处理方法

  • 删除含有异常值的记录
  • 视为缺失值:将异常值视为缺失值,按照缺失值进行处理
  • 平均值修正:可用前后两个观测值的平均值修正该异常值
  • 不处理:不直接在具有异常值的数据集上进行数据挖掘

是否要删除异常值可根据实际情况考虑。因为一些模型对异常值不很敏感,即使有异常值也不影响模型效果,但是一些模型比如逻辑回归LR对异常值很敏感,如果不进行处理,可能会出现过拟合等非常差的效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:黑客帝国 设计师:我叫白小胖 返回首页

打赏作者

可大侠

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值