zoukankan      html  css  js  c++  java
  • 【21年01月DW打卡】Task05

    异常检测——高维数据异常检测

    小结

    高维数据的特点:

    • 维度爆炸后,数据可能会一场稀疏
    • 在高维空间中,所有点对的距离几乎都是相等的(距离集中),这使得一些基于距离的方法失效

    集成方法:

    • Feature Bagging (特征组合)
      • 属于集成方法的一种,探索不同维度的子集,将这些基学习器集合起来
      • 可以自由将多个基学习器加入bagging中,如平均k近邻检测器会输出原始距离分数,而LOF算法会输出归一化值
    • 孤立森林
      • 该算法时间效率高,能有效处理高维数据和海量数据,无须标注样本
      • 适用于异常点稀有,可以根据特征分类来快速被排序二叉树剥离出来

    其他:

    • 教程学习出处
    • 转格式 jupyter nbconvert --to markdown E:PycharmProjectsTianChiProject0_山枫叶纷飞competitions11_dw_AnomalyDetection5_高维异常检测.ipynb

    1、引言

    在实际场景中,很多数据集都是多维度的。随着维度的增加,数据空间的大小(体积)会以指数级别增长,使数据变得稀疏,这便是维度诅咒的难题。维度诅咒不止给异常检测带来了挑战,对距离的计算,聚类都带来了难题。例如基于邻近度的方法是在所有维度使用距离函数来定义局部性,但是,在高维空间中,所有点对的距离几乎都是相等的(距离集中),这使得一些基于距离的方法失效。在高维场景下,一个常用的方法是子空间方法

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

    下面来介绍两种常见的集成方法:

    2、Feature Bagging

    Feature Bagging,基本思想与bagging相似,只是对象是feature。feature bagging属于集成方法的一种。集成方法的设计有以下两个主要步骤:

    0.bagging算法思想

    bagging是bootstrap aggregating的缩写。该算法的思想是让学习算法训练多轮,每轮的训练集由从初始的训练集中随机取出的n个训练样本组成,某个初始训练样本在某轮训练集中可以出现多次或根本不出现(即所谓的有放回抽样),训练之后可得到一个预测函数序列h_1,⋯ ⋯h_n ,最终的预测函数H对分类问题采用投票方式,对回归问题采用简单平均方法对新示例进行判别。上面的算法思想可通过下图来进行理解:


    图源: https://blog.csdn.net/chenyukuai6625/article/details/73692347

    步骤1. 选择基检测器

    这些基本检测器可以彼此完全不同,或不同的参数设置,或使用不同采样的子数据集。Feature bagging常用lof算法为基算法。下图是feature bagging的通用算法:

    翻译如下:

    • 给定:集合S = {(x1,y1),,,,(xm,ym)}, (x_i in X^d),标签为(y_i in Y = {C,NC}),其中C对应异常值,NC 对应正常类,d对应向量X的维度数目(特征数目)。
    • 归一化数据集S (如最大最小值归一化/正态归一化)
    • (For t=1,2,3,4,...T)
    1. 从符合均匀分布的特征维度(lfloor d/2 floor)和(d-1)中,随机选择一部分特征子集(N_t), 特征子集(N_t) 的维数(特征数)
    2. 随机选取(N_t)个特征,不进行替换,生成一个新的特征子集(F_t)
    3. 在新的特征子集(F_t)上使用异常检测算法(O_t)
    4. 异常检测算法的输出(O_t),就作为异常得分向量(AS_t)
    • 组合这些异常得分向量的正常得分向量,并且输出最终异常得分向量(AS_{FINAL}) as: (AS_{FINAL} = Combine(AS_t),t=1,2,...T)

    步骤2. 分数标准化和组合方法

    不同检测器可能会在不同的尺度上产生分数。例如,平均k近邻检测器会输出原始距离分数,而LOF算法会输出归一化值。
    另外,尽管一般情况是输出较大的异常值分数,但有些检测器会输出较小的异常值分数。因此,需要将来自各种检测器的分数转换成可以有意义的组合的归一化值。分数标准化之后,还要选择一个组合函数将不同基本检测器的得分进行组合,最常见的选择包括平均和最大化组合函数。

    下图是两个feature bagging两个不同的组合分数方法:

    广度优先

    - 枚举每一种基本检测器(共m种), 再嵌套枚举每一组异常值输出(共T种);
    - 每种异常检测算法分别检测T组样本数据,共有m*T种组合; 
    - 按照广度优先搜索,先到先占位,重复数据取后来的异常值的最大值、平均值等。
    

    累积求和

    - 针对每组样本,分别累加对应的全部的基本检测器的结果;共输出T组求和结果。
    

    集成学习的方差与偏差

    基探测器的设计及其组合方法都取决于特定集成方法的特定目标。很多时候,我们无法得知数据的原始分布,只能通过部分数据去学习。除此以外,算法本身也可能存在一定问题使得其无法学习到数据完整的信息。这些问题造成的误差通常分为偏差和方差两种。

    方差

    是指算法输出结果与算法输出期望之间的误差,描述模型的离散程度,数据波动性。

    偏差

    是指预测值与真实值之间的差距。即使在离群点检测问题中没有可用的基本真值

    3、Isolation Forests (多个随机二叉树组合成一片森林)

    简介

    孤立森林属于非参数和无监督的算法,既不需要定义数学模型也不需要训练数据有标签。孤立森林查找孤立点的策略非常高效。假设我们用一个随机超平面来切割数据空间,切一次可以生成两个子空间。然后我们继续用随机超平面来切割每个子空间并循环,直到每个子空间只有一个数据点为止。直观上来讲,那些具有高密度的簇需要被切很多次才会将其分离,而那些低密度的点很快就被单独分配到一个子空间了。孤立森林认为这些很快被孤立的点就是异常点。

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

    算法流程

    怎么来切这个数据空间是孤立森林的核心思想。因为切割是随机的,为了结果的可靠性,要用集成(ensemble)的方法来得到一个收敛值,即反复从头开始切,平均每次切的结果。孤立森林由t棵孤立的数组成,每棵树都是一个随机二叉树,也就是说对于树中的每个节点,要么有两个孩子节点,要么一个孩子节点都没有。树的构造方法和随机森林(random forests)中树的构造方法有些类似。流程如下:

    1.  从训练数据中随机选择一个样本子集,放入树的根节点;
      
    2.  随机指定一个属性,随机产生一个切割点V,即属性A的最大值和最小值之间的某个数;
      
    3.  根据属性A对每个样本分类,把A小于V的样本放在当前节点的左孩子中,大于等于V的样本放在右孩子中,这样就形成了2个子空间;
      
    4.  在孩子节点中递归步骤2和3,不断地构造左孩子和右孩子,直到孩子节点中只有一个数据,或树的高度达到了限定高度。
      

    获得t棵树之后,孤立森林的训练就结束,就可以用生成的孤立森林来评估测试数据。

    剥离异常点的思想:稀有的二叉树叶子结点

    孤立森林检测异常的假设是:异常点一般都是非常稀有的,在树中会很快被划分到叶子节点,因此可以用叶子节点到根节点的路径长度来判断一条记录是否是异常的。和随机森林类似,孤立森林也是采用构造好的所有树的平均结果形成最终结果的。在训练时,每棵树的训练样本是随机抽样的。从孤立森林的树的构造过程看,它不需要知道样本的标签,而是通过阈值来判断样本是否异常。因为异常点的路径比较短,正常点的路径比较长,孤立森林根据路径长度来估计每个样本点的异常程度。

    路径长度计算方法

    根节点到当前节点(必是叶子结点)的最短路径。
    计算方法

    • 二叉树的DFS或者BFS

    4、总结

    1. feature bagging可以降低方差,即是通过不同的基学习器进行组合,降低算法输出结果与算法输出期望之间的误差,达到一个较为稳定的状态。(可能会降低偏差)

    2. 孤立森林也是一种基于子空间的方法,不同的分支对应于数据的不同局部子空间区域,较小的路径对应于孤立子空间的低维;

      孤立森林的优势在于:

      • 计算成本相比基于距离或基于密度的算法更小。
      • 具有线性的时间复杂度。
      • 在处理大数据集上有优势。

    劣势:

     孤立森林不适用于超高维数据,因为孤立森林每次都是随机选取维度,如果维度过高,则会存在过多噪音。
    

    5、练习

    1.使用PyOD库生成toy example并调用feature bagging

    from pyod.models.feature_bagging import FeatureBagging
    from pyod.utils.data import generate_data
    from pyod.utils.data import evaluate_print
    from pyod.utils.example import visualize
    
    # 使用生成样本数据pyod.utils.data.generate_data():
    
    contamination = 0.1  # percentage of outliers
    n_train = 200  # number of training points
    n_test = 100  # number of testing points
    
    X_train, y_train, X_test, y_test = generate_data(
        n_train=n_train, n_test=n_test, contamination=contamination)
    
    # 初始化检测器,拟合模型,然后进行预测。
    
    # train FeatureBagging detector
    clf_name = 'FeatureBagging'
    
    
    clf = FeatureBagging()
    
    clf.fit(X_train)
    
    # get the prediction labels and outlier scores of the training data
    y_train_pred = clf.labels_  # binary labels (0: inliers, 1: outliers)
    y_train_scores = clf.decision_scores_  # raw outlier scores
    
    # get the prediction on the test data
    y_test_pred = clf.predict(X_test)  # outlier labels (0 or 1)
    y_test_scores = clf.decision_function(X_test)  # outlier scores
    
    # 使用ROC和Precision @ Rank n评估预测pyod.utils.data.evaluate_print()。
    
    from pyod.utils.data import evaluate_print
    # evaluate and print the results
    print("
    FeatureBagging On Training Data:")
    evaluate_print(clf_name, y_train, y_train_scores)
    print("
    FeatureBagging On Test Data:")
    evaluate_print(clf_name, y_test, y_test_scores)
    # 在培训和测试数据上查看示例输出。
    
    In D:Anaconda3libsite-packagesmatplotlibmpl-datastylelib\_classic_test.mplstyle: 
    The savefig.frameon rcparam was deprecated in Matplotlib 3.1 and will be removed in 3.3.
    In D:Anaconda3libsite-packagesmatplotlibmpl-datastylelib\_classic_test.mplstyle: 
    The verbose.level rcparam was deprecated in Matplotlib 3.1 and will be removed in 3.3.
    In D:Anaconda3libsite-packagesmatplotlibmpl-datastylelib\_classic_test.mplstyle: 
    The verbose.fileo rcparam was deprecated in Matplotlib 3.1 and will be removed in 3.3.
    D:Anaconda3libsite-packagespyodutilsdata.py:189: FutureWarning: behaviour="old" is deprecated and will be removed in version 0.8.0. Please use behaviour="new", which makes the returned datasets in the order of X_train, X_test, y_train, y_test.
      FutureWarning)
    
    
    
    FeatureBagging On Training Data:
    FeatureBagging ROC:0.9569, precision @ rank n:0.85
    
    FeatureBagging On Test Data:
    FeatureBagging ROC:0.98, precision @ rank n:0.9
    
    
    
    <Figure size 1200x1000 with 4 Axes>
    
    # 通过可视化所有示例中包含的功能来生成可视化。
    visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
                  y_test_pred, show_figure=True, save_figure=True)
    

    2.使用PyOD库生成toy example并调用Isolation Forests

    # train Isolation Forests detector
    clf_name = 'IsolationForest'
    from pyod.models.iforest import IForest
    
    clf = IForest()
    
    clf.fit(X_train)
    
    # get the prediction labels and outlier scores of the training data
    y_train_pred = clf.labels_  # binary labels (0: inliers, 1: outliers)
    y_train_scores = clf.decision_scores_  # raw outlier scores
    
    # get the prediction on the test data
    y_test_pred = clf.predict(X_test)  # outlier labels (0 or 1)
    y_test_scores = clf.decision_function(X_test)  # outlier scores
    
    # 使用ROC和Precision @ Rank n评估预测pyod.utils.data.evaluate_print()。
    
    from pyod.utils.data import evaluate_print
    # evaluate and print the results
    print("
    IsolationForest On Training Data:")
    evaluate_print(clf_name, y_train, y_train_scores)
    print("
    IsolationForest On Test Data:")
    evaluate_print(clf_name, y_test, y_test_scores)
    
    IsolationForest On Training Data:
    IsolationForest ROC:0.9481, precision @ rank n:0.8
    
    IsolationForest On Test Data:
    IsolationForest ROC:0.9722, precision @ rank n:0.9
    
    
    D:Anaconda3libsite-packagessklearnensembleiforest.py:223: FutureWarning: behaviour="old" is deprecated and will be removed in version 0.22. Please use behaviour="new", which makes the decision_function change to match other anomaly detection algorithm API.
      FutureWarning)
    

    3.(思考题:feature bagging为什么可以降低方差?)

    个人理解

    • 集成学习中,增加模型数量,可以有效提升综合模型的泛化能力,对于新的数据分布也会有比较好的适应性,总体到模型的输出比较稳定,可以有效降低方差。
      (注:方差拿自己的输出和预期比较,偏差是拿自己的输出和真实值进行比较)

    知乎 小小程序师

    通常来说boosting是在优化loss function,在降低loss,那么很显然,这在很大程度上是减少bias。
    
    而bagging,之所以进行bagging,是希望模型能够具有更好的鲁棒性,也就是稳定性,希望避免过拟合,显然这就是在减少variance。
    
    作者:小小程序师
    链接:https://www.zhihu.com/question/26760839/answer/65426153
    来源:知乎
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    

    方差和偏差的比较图

    模型的复杂度与 方差^2/偏差的趋势

    4.(思考题:feature bagging存在哪些缺陷,有什么可以优化的idea?)

    • 需要手动选择基学习器,针对每个基学习器都需要调整参数
      • 广撒网,捞小鱼呗
    • Feature Bagging的耗时严重,基学习器数量多

    6、参考文献

    [1]Goldstein, M. and Dengel, A., 2012. Histogram-based outlier score (hbos):A fast unsupervised anomaly detection algorithm . InKI-2012: Poster and Demo Track, pp.59-63.

    [2]https://cs.nju.edu.cn/zhouzh/zhouzh.files/publication/icdm08b.pdf

    [3]《Outlier Analysis》——Charu C. Aggarwal

    你不逼自己一把,你永远都不知道自己有多优秀!只有经历了一些事,你才会懂得好好珍惜眼前的时光!
  • 相关阅读:
    序言vue.js介绍
    python中end=''
    python文件的操作
    python异常
    python异常(理论知识)
    Uva 11300 Spreading the Wealth 中位数
    反转(开关问题) poj3276
    NEKO's Maze Game 思维
    Aaronson 一道思维题
    我开博客了
  • 原文地址:https://www.cnblogs.com/zhazhaacmer/p/14300626.html
Copyright © 2011-2022 走看看