Task05 异常检测_高维数据异常检测

主要内容包括:
Feature Bagging
孤立森林

1、概念

高维数据异常检测:现实生活中,一般一个数据集含有上千或者上万个维度,由于维护较多,有些异常很难识别出来。所以需要针对高维使用合适的异常检测方法。

1.1 高维异常检测的解决方案

1)如何做**维度选择(或者降维)**使得其在异常检测算法上运行效果比较好
2)集成学习分割子空间常用的技巧/经验
3)若是高维度但又稀疏呢?
4)是否还有其它的解决方案

1.2 方案介绍

1)数据降维和维度选择
**降维本质上是从一个维度空间映射到另一个维度空间,特征的多少没有减少,当然在映射的过程中特征值也会相应的变化。**举个例子,现在的特征是1000维,我们想要把它降到500维。降维的过程就是找个一个从1000维映射到500维的映射关系。原始数据中的1000个特征,每一个都对应着降维后的500维空间中的一个值。假设原始特征中有个特征的值是9,那么降维后对应的值可能是3。
**特征选择就是单纯地从提取到的所有特征中选择部分特征作为训练集特征,特征在选择前和选择后不改变值,但是选择后的特征维数肯定比选择前小,毕竟我们只选择了其中的一部分特征。**举个例子,现在的特征是1000维,现在我们要从这1000个特征中选择500个,那个这500个特征的值就跟对应的原始特征中那500个特征值是完全一样的。对于另个500个没有被选择到的特征就直接抛弃了。假设原始特征中有个特征的值是9,那么特征选择选到这个特征后它的值还是9,并没有改变。
2) 集成学习概述
集成学习在机器学习算法中具有较高的准确率,不足之处就是模型的训练过程可能比较复杂,效率不是很高。
分割子空间核心将多维度数据集,切割成多个多个子空间,分别针对多个子空间进行算法训练,再选用合适的方法利用合适的算法针对各个子空间进行集成预测结果。
对应m维空间,最大子空间数推导公式如下:
在这里插入图片描述
3)高维数据稀疏性
稀疏性:高维数据包含很多冗余信息,在计算过程中这些冗余信息是不需要甚至对结果有干扰的,因此需要采取某种手段尽量去除这些冗余信息,也就是使高维数据稀疏。

2、数据降维和维度选择

可参考Task3 PCA算法,维度选择可采用人工经验进行选择。

3、Feature Bagging

混淆矩阵也称误差矩阵,n行n列的表示矩阵,通过将每个实测像元的位置和分类与分类图像中的相应位置和分类相比较计算的。
在这里插入图片描述
Feature Bagging,基本思想与bagging相似,只是对象是feature。feature bagging属于集成方法的一种。集成方法的设计有以下两个主要步骤。

2.1 选择基检测器

每个子集可以先选择一个基检测算法,可使用不同的参数设置,或使用不同采样的子数据集,Feature bagging常用lof算法为基算法,下图是feature bagging的通用算法:
在这里插入图片描述
上述公式算法可与Task04:异常检测之基于相似度的方法LOF算法一起理解。

2.2 分数标准化和组合方法

使用不同的基检测算法在不同分割维度子集得到的结果分数以及权重不一致,例如:有些子集可输出较大的异常值分数,有些检测器会输出较小异常值分数,所以我们可将各个分割子集得到的分数进行归一化处理,再将分数进行标准化,还要选择一个组合函数将不同基本检测器的得分进行组合,最常见的选择包括平均和最大化组合函数。
下面为两个子集分使用算法
1)广度优先:
在这里插入图片描述2)累积求和
在这里插入图片描述
基探测器的设计及其组合方法都取决于特定集成方法的特定目标。很多时候,我们无法得知数据的原始分布,只能通过部分数据去学习。除此以外,算法本身也可能存在一定问题使得其无法学习到数据完整的信息。这些问题造成的误差通常分为偏差和方差两种。

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

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

4、决策树算法

孤立森林(Isolation Forest)算法是周志华教授等人于2008年提出的异常检测算法,是机器学习中少见的专门针对异常检测设计的算法之一,方法因为该算法时间效率高,能有效处理高维数据和海量数据,无须标注样本,在工业界应用广泛。
树算法思想的来源非常朴素,程序设计中的条件分支结构就是if-then结构,最早的决策树就是利用这类结构分割数据的一种分类学习方法,将满足条件和不满足条件的按一个个条件分割开来。
孤立森林属于非参数和无监督的算法,无需定义数学也不需要训练数据有标签。该算法非常高效。
举例:我们用一个随机平面来切割数据空间,会生成两个子空间,再用一个随机超平面来切割每个子空间,一直循环,直到所有的子空间只有一个数据点为止,直观来讲,那些具有高密度的簇需要被切很多次才会将其分离,而那些低密度的点很快就被单独分配到一个子空间了。
孤立森林认为这些很快被孤立的点就是异常点。
用四个样本做简单直观的理解,d是最早被孤立出来的,所以d最有可能是异常。
在这里插入图片描述
怎么来切这个数据空间是孤立森林的核心思想。因为切割是随机的,为了结果的可靠性,要用集成(ensemble)的方法来得到一个收敛值,即反复从头开始切,平均每次切的结果。孤立森林由t棵孤立的数组成,每棵树都是一个随机二叉树,也就是说对于树中的每个节点,要么有两个孩子节点,要么一个孩子节点都没有。树的构造方法和随机森林(random forests)中树的构造方法有些类似。流程如下:

  1. 从训练数据中随机选择一个样本子集,放入树的根节点;
  2. 随机指定一个属性,随机产生一个切割点V,即属性A的最大值和最小值之间的某个数;
  3. 根据属性A对每个样本分类,把A小于V的样本放在当前节点的左孩子中,大于等于V的样本放在右孩子中,这样就形成了2个子空间;
  4. 在孩子节点中递归步骤2和3,不断地构造左孩子和右孩子,直到孩子节点中只有一个数据,或树的高度达到了限定高度。
    获得t棵树之后,孤立森林的训练就结束,就可以用生成的孤立森林来评估测试数据。
    孤立森林检测异常的假设是:异常点一般都是非常稀有的,在树中会很快被划分到叶子节点,因此可以用叶子节点到根节点的路径长度来判断一条记录是否是异常的。和随机森林类似,孤立森林也是采用构造好的所有树的平均结果形成最终结果的。在训练时,每棵树的训练样本是随机抽样的。从孤立森林的树的构造过程看,它不需要知道样本的标签,而是通过阈值来判断样本是否异常。因为异常点的路径比较短,正常点的路径比较长,孤立森林根据路径长度来估计每个样本点的异常程度。
    在这里插入图片描述
    孤立森林也是一种基于子空间的方法,不同的分支对应于数据的不同局部子空间区域,较小的路径对应于孤立子空间的低维。

5、总结

  1. feature bagging优势:
    可以降低方差,可以给不同维度组合采用最合适的算法,依据权重最终得到一个整体较高的训练结果。
    2.孤立森林的优势:
    计算成本相比基于距离或基于密度的算法更小。
    具有线性的时间复杂度。
    在处理大数据集上有优势。
    孤立森林不适用于超高维数据,因为鼓励森林每次都是随机选取维度,如果维度过高,则会存在过多噪音。

6、练习

6.1 feature bagging

使用PyOD库生成toy example并调用feature bagging
由于为高维的故使用之前annthyroid-unsupervised-ad.csv维度较多数据集进行训练。

from pyod.models.feature_bagging import FeatureBagging #Use PCAalgorithm
from pyod.utils.data import evaluate_print #evaluate result
from pyod.utils.example import visualize #draw
from sklearn.model_selection import train_test_split #cut the data
import pandas as pd #pa
if __name__ == "__main__":
    path = 'dataverse_files/'
    f = open(path + 'annthyroid-unsupervised-ad.csv')
    titan = pd.read_csv(f,nrows=300)

    # deal data
    #x = titan[['f0','f20']]
    x = titan[['f' + str(i) for i in range(21)]]
    #print(['f' + str(i) for i in range(21)])
    #print(x)
    y = titan['label'].replace("n",1).replace("o",0)
    #print(y)
    # cut the data
    X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
    #print(X_test.value_counts())
    # print(y_train)
    # print(X_test)c
    # print(y_test)

    # train kNN detector
    clf_name = 'FeatureBagging'
    clf = FeatureBagging()
    clf.fit(X_train)

    #print(X_train)
    # get the prediction labels and outlier scores of the training data
    y_train_pred = clf.labels_  # binary labels (0: inliers, 1: outliers)
    print(y_train_pred)
    y_train_scores = clf.decision_scores_  # raw outlier scores
    print(y_train_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
    #print(y_test_pred)
    # evaluate and print the results
    print("\nOn Training Data:")
    evaluate_print(clf_name, y_train, y_train_scores)
    print("\nOn Test Data:")
    evaluate_print(clf_name, y_test, y_test_scores)
    #print(X_train)
  
    visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
              y_test_pred, show_figure=True, save_figure=True)

预测结果展示:
On Training Data:
FeatureBagging ROC:0.6514, precision @ rank n:0.1944
On Test Data:
FeatureBagging ROC:0.7026, precision @ rank n:0.5

在这里插入图片描述

6.2 孤立森林

from pyod.models.iforest  import IForest #Use PCAalgorithm
from pyod.utils.data import evaluate_print #evaluate result
from pyod.utils.example import visualize #draw
from sklearn.model_selection import train_test_split #cut the data
import pandas as pd #pa
if __name__ == "__main__":
    path = 'dataverse_files/'
    f = open(path + 'annthyroid-unsupervised-ad.csv')
    titan = pd.read_csv(f,nrows=300)

    # deal data
    #x = titan[['f0','f20']]
    x = titan[['f' + str(i) for i in range(21)]]
    #print(['f' + str(i) for i in range(21)])
    #print(x)
    y = titan['label'].replace("n",1).replace("o",0)
    #print(y)
    # cut the data
    X_train, X_test, y_train, y_test = train_test_split(x, y, test_size=0.25)
    #print(X_test.value_counts())
    # print(y_train)
    # print(X_test)c
    # print(y_test)

    # train kNN detector
    clf_name = 'IForest'
    clf = IForest()
    clf.fit(X_train)

    #print(X_train)
    # get the prediction labels and outlier scores of the training data
    y_train_pred = clf.labels_  # binary labels (0: inliers, 1: outliers)
    print(y_train_pred)
    y_train_scores = clf.decision_scores_  # raw outlier scores
    print(y_train_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
    #print(y_test_pred)
    # evaluate and print the results
    print("\nOn Training Data:")
    evaluate_print(clf_name, y_train, y_train_scores)
    print("\nOn Test Data:")
    evaluate_print(clf_name, y_test, y_test_scores)
    #print(X_train)
    X_train = X_train[['f0', 'f20']]
    X_test = X_test[['f0', 'f20']]
    visualize(clf_name, X_train, y_train, X_test, y_test, y_train_pred,
              y_test_pred, show_figure=True, save_figure=True)

预测结果展示:
On Training Data:
IForest ROC:0.6153, precision @ rank n:0.275
On Test Data:
IForest ROC:0.68, precision @ rank n:0.4

在这里插入图片描述

6.3 思考题1-feature bagging为什么可以降低方差?

方差概念:统计中的方差(样本方差)是每个样本值与全体样本值的平均数之差的平方值的平均数。
feature bagging核心可以给不同维度组合采用最合适的算法,依据权重最终得到一个整体较高的训练结果。依据方差的原理。feature bagging可以选择合适的维度组合,使每个样本值与整体平均值差距不大,从而降低方差。

6.3 思考题2-feature bagging存在哪些缺陷,有什么可以优化的idea?

缺陷:

  1. 如何切割分类成各个组合维度子数据集,需要非常了解此数据集的人进行分类
  2. feature bagging需要给每个子数据集选择合适的基检测器,难度较大
  3. 如何控制各个子数据及训练结果的权重比例,也较为困难
    优化idea:
  4. 找经验丰富的业务人员进行维度子集切割
  5. 用相对较好的基检测器将大多数明显异常值筛选出来,然后再选用合适的算法进一步筛选异常值
  6. 依据各个子集的训练结果,以及结合业务人员的判断,给各个维度的定义合适的权重比例
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值