美文网首页人工智能基础知识
异常检测(一)概述

异常检测(一)概述

作者: 许志辉Albert | 来源:发表于2021-01-12 09:29 被阅读0次

    1异常检测概述

    image.png

    2异常检测常用方法

    传统方法

    基于传统统计学方法

    统计学方法对数据的正常性做出假定。它们假定正常的数据对象由一个统计模型产生,而不遵守该模型的数据是异常点。统计学方法的有效性高度依赖于对给定数据所做的统计模型假定是否成立。

    异常检测的统计学方法的一般思想是:学习一个拟合给定数据集的生成模型,然后识别该模型低概率区域中的对象,把它们作为异常点。

    即利用统计学方法建立一个模型,然后考虑对象有多大可能符合该模型。(很多时候一些数据分析的异动告警也是利用这样的方法,当某些数据在三个\sigma之外,就会被视为异常)

    假定输入数据集为{x^{(1)}, x^{(2)}, ..., x^{(m)}},数据集中的样本服从正态分布,即x^{(i)}\sim N(\mu, \sigma^2),我们可以根据样本求出参数\mu\sigma

    \mu=\frac 1m\sum_{i=1}^m x^{(i)}

    \sigma^2=\frac 1m\sum_{i=1}^m (x^{(i)}-\mu)^2

    线性模型

    典型的如PCA方法,Principle Component Analysis是主成分分析,简称PCA。它的应用场景是对数据集进行降维。降维后的数据能够最大程度地保留原始数据的特征(以数据协方差为衡量标准)。 PCA的原理是通过构造一个新的特征空间,把原数据映射到这个新的低维空间里。PCA可以提高数据的计算性能,并且缓解"高维灾难"。
    PCA降维的一个基本点与两个原则,一个基本点:中心化;两个基本原则:最大投影方差(即点与点之间投影后的距离越远越好),最小重构代价(对降维后的数据进行升维之后,信息损失越小越好)

    基于相似度的方法

    这类算法适用于数据点的聚集程度高、离群点较少的情况。同时,因为相似度算法通常需要对每一个数据分别进行相应计算,所以这类算法通常计算量大,不太适用于数据量大、维度高的数据。
      基于相似度的检测方法大致可以分为三类:

    • 基于集群(簇)的检测,如DBSCAN等聚类算法。
        聚类算法是将数据点划分为一个个相对密集的“簇”,而那些不能被归为某个簇的点,则被视作离群点。这类算法对簇个数的选择高度敏感,数量选择不当可能造成较多正常值被划为离群点或成小簇的离群点被归为正常。因此对于每一个数据集需要设置特定的参数,才可以保证聚类的效果,在数据集之间的通用性较差。聚类的主要目的通常是为了寻找成簇的数据,而将异常值和噪声一同作为无价值的数据而忽略或丢弃,在专门的异常点检测中使用较少。
        聚类算法的优缺点:
      (1)能够较好发现小簇的异常;
      (2)通常用于簇的发现,而对异常值采取丢弃处理,对异常值的处理不够友好;
      (3)产生的离群点集和它们的得分可能非常依赖所用的簇的个数和数据中离群点的存在性;
      (4)聚类算法产生的簇的质量对该算法产生的离群点的质量影响非常大。
    • 基于距离的度量,如k近邻算法。
        k近邻算法的基本思路是对每一个点,计算其与最近k个相邻点的距离,通过距离的大小来判断它是否为离群点。在这里,离群距离大小对k的取值高度敏感。如果k太小(例如1),则少量的邻近离群点可能导致较低的离群点得分;如果k太大,则点数少于k的簇中所有的对象可能都成了离群点。为了使模型更加稳定,距离值的计算通常使用k个最近邻的平均距离。
        k近邻算法的优缺点:
      (1)简单;
      (2)基于邻近度的方法需要O(m2)时间,大数据集不适用;
      (3)对参数的选择敏感;
      (4)不能处理具有不同密度区域的数据集,因为它使用全局阈值,不能考虑这种密度的变化。
    • 基于密度的度量,如LOF(局部离群因子)算法。
        局部离群因子(LOF)算法与k近邻类似,不同的是它以相对于其邻居的局部密度偏差而不是距离来进行度量。它将相邻点之间的距离进一步转化为“邻域”,从而得到邻域中点的数量(即密度),认为密度远低于其邻居的样本为异常值。
      LOF(局部离群因子)算法的优缺点:
      (1)给出了对离群度的定量度量;
      (2)能够很好地处理不同密度区域的数据;
      (3)对参数的选择敏感。

    集成方法

    集成是提高数据挖掘算法精度的常用方法。集成方法将多个算法或多个基检测器的输出结合起来。其基本思想是一些算法在某些子集上表现很好,一些算法在其他子集上表现很好,然后集成起来使得输出更加鲁棒。集成方法与基于子空间方法有着天然的相似性,子空间与不同的点集相关,而集成方法使用基检测器来探索不同维度的子集,将这些基学习器集合起来。

    常用的集成方法有Feature bagging,孤立森林等。

    feature bagging

    与bagging法类似,只是对象是feature。

    孤立森林:

    孤立森林假设我们用一个随机超平面来切割数据空间,切一次可以生成两个子空间。然后我们继续用随机超平面来切割每个子空间并循环,直到每个子空间只有一个数据点为止。直观上来讲,那些具有高密度的簇需要被切很多次才会将其分离,而那些低密度的点很快就被单独分配到一个子空间了。孤立森林认为这些很快被孤立的点就是异常点。

    用四个样本做简单直观的理解,d是最早被孤立出来的,所以d最有可能是异常。


    孤立森林

    机器学习

    在有标签的情况下,可以使用树模型(gbdt,xgboost等)进行分类,缺点是异常检测场景下数据标签是不均衡的,但是利用机器学习算法的好处是可以构造不同特征。

    异常检测常用开源库

    Sklearn & PyOD

    https://zhuanlan.zhihu.com/p/58313521
    知乎专栏对PyOD做了详细的说明,下面我就简单的说一下常用API

    https://pyod.readthedocs.io/en/latest/
    PyOD官网

    PyOD

    Python Outlier Detection(PyOD)的亮点

    • 包括了20种常见的异常检测算法,比如经典的LOF/LOCI/ABOD以及最新的深度学习如对抗生成模型(GAN)和集成异常检测(outlier ensemble)
    • 支持不同版本的Python:包括2.7 和3.5+;支持多种操作系统:windows,macOS和Linux
    • 简单易用且一致的API,只需要几行代码就可以完成异常检测,方便大量评估算法
    • 使用JIT和并行化(parallelization)进行优化,加速算法运行及拓展性(scalability),可以处理大量数据

    1.背景

    PyOD提供了约20种异常检测算法(详见图1)部分算法介绍可以参考「数据挖掘中常见的「异常检测」算法有哪些?」或异常检测领域的经典教科书[7]。同时该工具库也包含了一系列辅助功能,包括数据可视化及结果评估等:

    PyOD中所包括的算法一栏

    2.API介绍与实例

    特别需要注意的是,异常检测算法基本都是无监督学习,所以只需要X(输入数据),而不需要y(标签)。PyOD的使用方法和Sklearn中聚类分析很像,它的检测器(detector)均有统一的API。所有的PyOD检测器clf均有统一的API以便使用,完整的API使用参考可以查阅(API CheatSheet - pyod 0.6.8 documentation):

    • fit(x):用数据x来“训练/拟合“ 检测器clf。即初始化检测器clf后,用X来训练它
    • fit_predict_score(x,y):用数据x来训练检测器clf,并预测x的预测值,并在真实标签y上进行评估,此处的y只用于评估,而非训练
    • decision_function(x):在检测器clf被fit后,可以通过函数来预测未知数据的异常程度,返回值为原始分数,并非0或1。返回分数越高,则该数据点的异常程度越高
    • predict(X):在检测器clf被fit后,预测未知数据的异常概率,返回该点是异常点的概率

    当检测器clf被初始化且fitx(x)函数被执行后,clf就会生成两个重要的属性:

    • decision_scores:数据x上的异常打分,分数越高,则该异常点的异常成都越高
    • labels_:数据X上的异常标签,返回值为二分类标签(0为正常点,1位异常点)

    不难看出,当我们初始化一个检测器clf后,可以直接用数据X来“训练”clf,之后我们便可以得到X的异常分值(clf.decision_scores)以及异常标签(clf.labels_)。当clf被训练后(当fit函数被执行后),我们可以使用decision_function()和predict()函数来对未知数据进行训练。

    简单的异常检测

    from pyod.models.knn import KNN   # imprt kNN分类器
    
    # 训练一个kNN检测器
    clf_name = 'kNN'
    clf = KNN() # 初始化检测器clf
    clf.fit(X_train) # 使用X_train训练检测器clf
    
    # 返回训练数据X_train上的异常标签和异常分值
    y_train_pred = clf.labels_  # 返回训练数据上的分类标签 (0: 正常值, 1: 异常值)
    y_train_scores = clf.decision_scores_  # 返回训练数据上的异常值 (分值越大越异常)
    
    # 用训练好的clf来预测未知数据中的异常值
    y_test_pred = clf.predict(X_test)  # 返回未知数据上的分类标签 (0: 正常值, 1: 异常值)
    y_test_scores = clf.decision_function(X_test)  #  返回未知数据上的异常值 (分值越大越异常)
    

    不难看出,PyOD的API和scikit-learn非常相似,只需要几行就可以得到数据的异常值。当检测器得到输出后,我们可以用以下代码评估其表现,或者直接可视化分类结果

    
    # 评估预测结果
    print("\nOn Test Data:")
    evaluate_print(clf_name, y_test, y_test_scores)
    
    # 可视化
    visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
        y_test_pred, show_figure=True, save_figure=False)
    
    可视化结果——来源知乎

    相关文章

      网友评论

        本文标题:异常检测(一)概述

        本文链接:https://www.haomeiwen.com/subject/mfpjaktx.html