异常检测 Task 1

一、什么是异常检测

异常检测是机器学习种一个非常重要的分支,从定义而言,异常检测(Outlier Detection)是识别与正常数据不同的数据,与预期行为差异大的数据。比如在数据挖掘领域中的信用卡盗刷、超大金额支出、网络入侵等;在计算机视觉领域中的不符合分类的图片等。

1、异常的类别

点异常 Point (点集):指少数个体实例时异常的,大多数个体实例是正常的。比如每天的支出都在1元、2元,如果有一天支出1万元,就可以出现了异常;比如健康和非健康人的健康指标。如下图, o 1 , o 2 o_1, o_2 o1,o2 属于点异常。
在这里插入图片描述

上下文异常 Contextual or Conditional (连续集):上下文相关的连续数据,某一个中间数据出现了异常情况,可能引起了梯度消失爆炸等等问题。如下图: t 2 t_2 t2 属于上下文异常。
在这里插入图片描述
参考论文:

  • Xiuyao Song, Mingxi Wu, Christopher Jermaine, and Sanjay Ranka.
    Conditional anomaly detection. IEEE Transactions on Knowledge and
    Data Engineering, 19(5):631–645, 2007.

群体异常 Collective or Group(团队集):指在群体集合中的个体实例出现异常的情况,而个体实例自身可能并不是异常。例如社交网络中虚假账号形成的集合作为群体异常子集,但子集中的个体节点可能与真是账号一样正常。例如还是之前的信用卡,突然短时间内不停的消费2元,那可能这很多的2元支出形成的数据集为全体异常子集,但子集内每笔支出与你平时正常支出无异。如下图,红色箭头所指的红框区域属于群体异常。
在这里插入图片描述
参考论文:

  • Raghavendra Chalapathy, Edward Toth, and Sanjay Chawla. Group anomaly detection using deep generative models. arXiv preprint arXiv:1804.04876, 2018b.
  • Lo¨ıc Bontemps, James McDermott, Nhien-An Le-Khac, et al. Collective anomaly detection based on long short-term memory recurrent neural networks. In International Conference on Future Data and Security Engineering, pages 141–152. Springer, 2016.
  • Daniel B Araya, Katarina Grolinger, Hany F ElYamany, Miriam AM Capretz, and G Bitsuamlak. Collective contextual anomaly detection framework for smart buildings. In Neural Networks (IJCNN), 2016 International Joint Conference on, pages 511–518. IEEE, 2016.
  • Naifan Zhuang, Tuoerhongjiang Yusufu, Jun Ye, and Kien A Hua. Group activity recognition with differential recurrent convolutional neural networks. In Automatic Face & Gesture Recognition (FG 2017), 2017 12th IEEE International Conference on, pages 526–531. IEEE, 2017.
2、异常检测任务分类

有监督 Supervised DAD:训练集的正例和反例均有标签,学习分离边界训练一个监督二分类或多分类。但是监督学习对于标签内容的依赖度过重,所以对于异常检测的问题不是很合适,不如半监督和无监督应用的那么广泛。例如普通的神经网络,输入带标签的数据,利用反向传播算法训练纠正神经网络权值,用作多分类。虽然在深度神经网络的加持下有监督异常检测的性能有所提高,但由于缺乏标记训练样本,应用并没有得到广泛的应用。此外,有监督异常检测分类器由于类的不平衡性(正类实例的总数远远大于负类数据总数),其性能是次优的。

无监督 Unsupervised DAD:训练集无标签,基于数据实例的固有属性(通过隐藏层捕捉内在属性,识别数据共性),无监督技术对未标记数据样本进行自动标记。自动编码器是无监督模型的核心,这些模型假设正常实例的发生率高于异常实例。现有的无监督学习算法包括RBM、DBM、DBN、RNN、LSTM等比传统的PCA、SVM和IF等方法具有更好的性能。但无监督技术对噪声十分敏感,往往不如有监督和半监督准确。

半监督 Semi-supervised DAD:在训练集中只有单一类别(正常实例)的实例,没有异常实例参与训练。由于正常数据集比异常数据集更好获得,所以半监督学习DAD方法被非常广泛的使用。半监督技术利用单个类的现有标签分离异常值,即半监督或One Class问题假定所有训练实例都只有一个类标签。常见的方法是在正常数据样本上,利用部分有标签的“正常”数据和无标签数据(学习无标签数据中的信息辅助“监督学习”),半监督训练出一个对正常数据重构误差小的AE。即使在标记数据很少的情况下,以半监督训练GAN的方法,使用少量正常训练GAN得到一个精确度尽可能高的排除异常的D。与无监督技术相比显著提高性能,其缺点是,隐藏层提取出的分层特征可能出现过拟合问题。

监督学习方法依赖于分离数据类,而无监督学习方法则专注于解释和理解数据的特征。其计算复杂度取决于输入数据维数和反向传播算法的隐藏层数。当特征空间高度复杂和非线性时,普通神经网络不涉及降维无法对高维数据有很好的理解,此时有监督技术无法将正常数据与异常数据分开。

3、异常检测场景
  • 故障检测
  • 医疗日常监测
  • 网络入侵检测
  • 欺诈检测
  • 工业异常检测
  • 时间序列异常检测
  • 视频异常检测
  • 日志异常检测
4、异常检测的难点

1、数据量少,通常负样本的例比比较少,样本不均衡。
2、常常存在噪音和异常点混杂在一起的情况,难以区分。

比较常用的手段是无监督学习方法和专家经验相结合,基于无监督学习得到检测结果,并让领域专家基于检测结果给出反馈,以便于我们及时调整模型,反复进行迭代,最终得到一个越来越准确的模型。

二、异常检测方法简介

1、基础方法

1.1 基于统计学的方法

统计学方法对数据的正常性做出假定:

  • 假定正常的数据对象由一个统计模型产生,而不遵守该模型的数据是异常点。
  • 统计学方法的有效性高度依赖于对给定数据所作的统计模型假定是否成立。
  • 一般思想是:学习一个拟合给定数据集的生成模型,然后识别该模型低概率区域中的对象,把它们作为异常点。
    在这里插入图片描述

比如高斯分布,在平均值加减3倍标准差以外的部分仅占了0.2%左右的比例,一般我们把这部分数据就标记为异常数据。使用这种方法存在的问题是,均值和方差本身都对异常值很敏感,因此如果数据本身不具备正态性,就不适合使用这种检测方法。

1.2 线性模型

典型的如PCA方法,Principle Component Analysis是主成分分析,简称PCA。它的应用场景是对数据集进行降维。降维后的数据能够最大程度地保留原始数据的特征(以数据协方差为衡量标准)。其原理是通过构造一个新的特征空间,把原数据映射到这个新的低维空间里。PCA可以提高数据的计算性能,并且缓解"高维灾难"。

什么是降维?
降维是指通过保留一些比较重要的特征,去除一些冗余的特征,减少数据特征的维度。而特征的重要性取决于该特征能够表达多少数据集的信息,也取决于使用什么方法进行降维。一般情况会先使用线性的降维方法再使用非线性的降维方法,通过结果去判断哪种方法比较合适。

1.3 基于邻近度的方法

适用情况:数据点聚集程度高、离群点较少。

不适用情况:因为相似度算法通常需要对每一个数据分别进行相应计算,所以这类算法通常计算量大,不适用于数据量大、维度高的数据。

基于相似度的检测方法大致可以分为:

  • 基于集群(簇)的检测,如DBSCAN等聚类算法。
    聚类算法是将数据点划分为一个个相对密集的“簇”,而那些不能被归为某个簇的点,则被视作离群点。这类算法对簇个数的选择高度敏感,数量选择不当可能造成较多正常值被划为离群点或成小簇的离群点被归为正常。或成小簇的离群点被归为正常。因此对于每一个数据集需要设置特定的参数,才可以保证聚类的效果,在数据集之间的通用性较差。聚类的主要目的通常是为了寻找成簇的数据,而将异常值和噪声一同作为无价值的数据而忽略或丢弃,在专门的异常点检测中使用较少。

  • 基于距离的度量,如k近邻算法。
    k近邻算法的基本思路是对每一个点,计算其与最近k个相邻点的距离,通过距离的大小来判断它是否为离群点。在这里,离群距离大小对k的取值高度敏感。如果k太小(例如1),则少量的邻近离群点可能导致较低的离群点得分;如果k太大,则点数少于k的簇中所有的对象可能都成了离群点。为了使模型更加稳定,距离值的计算通常使用k个最近邻的平均距离。

    • k-NN也是一种懒算法,意思是说k-NN在训练过程中主要是存储数据集,并不会做过多的事情。
    • k近邻算法的优缺点:简单;基于邻近度的方法需要O(m2)时间,大数据集不适用;对参数的选择敏感;不能处理具有不同密度区域的数据集,因为它使用全局阈值,不能考虑这种密度的变化。
  • 基于密度的度量,如LOF(局部离群因子)算法。
    ​ 局部离群因子(LOF)算法与k近邻类似,不同的是它以相对于其邻居的局部密度偏差而不是距离来进行度量。它将相邻点之间的距离进一步转化为“邻域”,从而得到邻域中点的数量(即密度),认为密度远低于其邻居的样本为异常值。

    • LOF算法的优缺点:给出了对离群度的定量度量;能够很好地处理不同密度区域的数据;对参数的选择敏感。
      在这里插入图片描述
2、集成方法

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

2.1 Feature bagging

与bagging类似,区别是对象是feature
在这里插入图片描述
所谓 Feature Bagging 是对特征集合取样K个特征。每一棵策树的每一个结点分裂,RF(Random Forests)都从特征集合中取样,并且每一次取样都互不影响。RF的的决策树生成算法如下:
在这里插入图片描述

如果特征集合的基较小,即特征数量不足,则很难采样出相互独立的特征集合。RF采取了线性加权的方式组合(Linear Combinations of Inputs)成新feature,形成新的特征集合。

参考论文:
https://people.cs.umass.edu/mccallum/papers/ir402bags.pdf#::text=feature%20bagging%2C%20in%20which%20separate%20models%20are%20trained,tasks%2C%20the%20feature-bagged%20CRF%20performs%20better%20than%20sim-

2.2 孤立森林(Isolation Forest)

在孤立森林(iForest)中,异常数据被定义为“ 容易被孤立的离群点 (more likely to be separated) ”,可以将其理解为分布稀疏且离密度高的群体较远的点。在特征空间里,分布稀疏的区域表示事件发生在该区域的概率很低,因而可以认为落在这些区域里的数据是异常的。孤立森林是一种适用于连续数据(Continuous numerical data)的无监督异常检测方法,即不需要有标记的样本来训练,但特征需要是连续的。对于如何查找哪些点容易被孤立(isolated),iForest使用了一套非常高效的策略。

孤立森林假设我们用一个随机超平面来切割数据空间,切一次可以生成两个子空间。然后我们继续用随机超平面来切割每个子空间并循环,直到每个子空间只有一个数据点为止。直观上来讲,那些具有高密度的簇需要被切很多次才会将其分离,而那些低密度的点很快就被单独分配到一个子空间了。孤立森林认为这些很快被孤立的点就是异常点。
在这里插入图片描述
在图(a)和图(b)中,可以看到正常点 x i x_i xi 需要更多次的分割才能被孤立,而异常点 x 0 x_0 x0 需要较少的分割次数就能被孤立。这里的分割方式采用的是随机选择一个特征以及拆分的值(这个值位于该特征的最小值和最大值之间)。图(c)展示了异常点的平均路径长度小于正常点的路径长度

3、机器学习

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

三、异常检测常用的开源库

1、Scikit-learn

支持4种异常检测方法:LOF、Isolation Forests、OnelClassSVM、EllipticEnvelope

OneClassSVM:对离群值非常敏感,因此在离群值检测方面表现得不是很好。该估计器最适合于训练集不受异常值污染时的新颖性检测。也就是说,在高维或者没有对内嵌数据的分布做任何假设的情况下进行离群点检测是非常具有挑战性的,而One-class SVM可能会根据其超参数的值在这些情况下给出有用的结果。

EllipticEnvelope:假设数据是高斯的,并学习一个椭圆。因此,当数据不是单模态时,它会退化。但是请注意,这个估计器对离群值是稳健的。

IsolationForest和LocalOutlierFactor:对于多模态数据集,表现得相当好。LocalOutlierFactor 比其他估计器的优势为当其中两个模式有不同的密度的第三个数据集。这种优势可以用LOF的局部特性来解释,这意味着它只将一个样本的异常分数与其相邻样本的异常分数进行比较。

1.1 代码示例:

make_blobs方法:

sklearn.datasets.make_blobs(n_samples=100,n_features=2,centers=3, cluster_std=1.0,center_box=(-10.0,10.0),shuffle=True,random_state=None)
  • make_blobs函数是为聚类产生数据集,产生一个数据集和相应的标签
  • n_samples:表示数据样本点个数,默认值100
  • n_features:是每个样本的特征(或属性)数,也表示数据的维度,默认值是2 centers:表示类别数(标签的种类数),默认值3
  • cluster_std表示每个类别的方差,例如我们希望生成2类数据,其中一类比另一类具有更大的方差,可以将cluster_std设置为[1.0,3.0],浮点数或者浮点数序列,默认值1.0
  • center_box:中心确定之后的数据边界,默认值(-10.0, 10.0) shuffle :将数据进行洗乱,默认值是True
  • random_state:官网解释是随机生成器的种子,可以固定生成的数据,给定数之后,每次生成的数据集就是固定的。若不给定值,则由于随机性将导致每次运行程序所获得的的结果可能有所不同。在使用数据生成器练习机器学习算法练习或python练习时建议给定数值。

make_moons:

生成半环形图

sklearn.datasets.make_moons(n_samples=100, shuffle=True, noise=None, random_state=None)
from sklearn.datasets import make_circles  
from sklearn.datasets import make_moons  
import matplotlib.pyplot as plt  
import numpy as np  
  
fig=plt.figure(1)  
x1,y1=make_circles(n_samples=1000,factor=0.5,noise=0.1)
# datasets.make_circles()专门用来生成圆圈形状的二维样本.factor表示里圈和外圈的距离之比.每圈共有n_samples/2个点,、
plt.subplot(121)  
plt.title('make_circles function example')  
plt.scatter(x1[:,0],x1[:,1],marker='o',c=y1)  
  
plt.subplot(122)  
x1,y1=make_moons(n_samples=1000,noise=0.1)  
plt.title('make_moons function example')  
plt.scatter(x1[:,0],x1[:,1],marker='o',c=y1)  
plt.show() 

在这里插入图片描述

文档:
https://scikit-learn.org/stable/auto_examples/miscellaneous/plot_anomaly_comparison.html?highlight=anomaly

在官网中查看这四种算法在数据集上的分类效果比较。
在这里插入图片描述

2、PyOD

Python Outlier Detection(PyOD)是一个Python异常检测工具库,除了支持Sklearn上支持的四种模型外,还额外提供了很多模型如:

  • 传统异常检测方法:HBOS、PCA、ABOD和Feature Bagging等。
  • 基于深度学习与神经网络的异常检测:自编码器(keras实现)。

其主要亮点包括:

  • 包括近20种常见的异常检测算法,比如经典的LOF/LOCI/ABOD以及最新的深度学习如对抗生成模型(GAN)和集成异常检测(outlier ensemble)
  • 所有算法共享通用的API,方便快速调包,同时支持Python2和3。支持多种操作系统:windows,macOS和Linux。
  • 代码经过了重重优化,大部分模型通过了并行与即时编译。使用JIT和并行化(parallelization)进行优化,加速算法运行及扩展性(scalability),可以处理大量数据
  • 提供了详细的文档以及大量例子,方便快速上手

2.1 代码示例

简单来说,一个完整的pyod训练模型分为以下几步:

  • 生成数据集或引用现成数据集
  • 在训练集上训练模型
  • 预测测试集的结果
  • 给出模型评估分数
  • 可视化模型结果(高维数据集难以可视化)
from pyod.models.knn import KNN
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 pints

X_train, y_train, X_test, y_test = generate_data(n_train=n_train, n_test=n_test, contamination=contamination)

# fit and predict 
# 训练KNN模型
clf_name = 'KNN'
clf = KNN()
clf.fit(X_train) # 训练时无需输入y参数

# get the prediction labels and outlier scores of the training data
y_train_pred = clf.labels_  # 0正常,1异常
y_train_scores = clf.decision_scores_ # 数值越大越异常

# 用训练好的模型预测测试数据的标签和分数
y_test_pred = clf.predict(X_test)

# decision_function代表的是参数实例到各个类所代表的超平面的距离;
# 在梯度下滑里面特有的(随机森林里面没有decision_function),这个返回的距离,或者说是分值;
# 后续的对于这个值的利用方式是指定阈值来进行过滤:
y_test_scores = clf.decision_function(X_test)

# 使用ROC和Precision @ Rank n 评估预测
# evaluate and print the results

print("On Training Data:")
evaluate_print(clf_name, y_train, y_train_scores)
print("On 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://pyod.readthedocs.io/en/latest/pyod.html

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值