浏览器中的深度学习:TensorFlow.js (XII)异常检测算法

异常检测是机器学习领域常见的应用场景,如金融领域的信用卡欺诈、企业安全领域的非法入侵,以及预测设备在信息技术运行和维护中的维护时间点。今天,让我们看看异常检测的基本概念和算法,然后看看如何使用TensorflowJS进行异常检测。

什么是异常值?

异常点是指数据中与其他点不同的点。异常检测就是找到这些点。通常有以下不同类型的异常:点异常

单个点与其他数据明显不同

上下文异常

数据在其所处的上下文中是异常的。例如,下图中的t1并不异常,而t2是由于t2和t2前后的数据存在显著差异。

集体异常。

收集异常是指一组数据点与其他数据显著不同,并且这组数据的收集构成异常

从数据维度来看,异常也分为单变量异常和多变量异常。

异常检测算法主要包括基于统计的算法和基于机器学习的算法。

异常检测的统计方法

异常检测有两种统计方法。第一种是参数化的,即假设正态数据基于某个参数分布,那么我们可以通过训练数据来估计数据的分布概率,然后计算在这个概率分布下每个待分析数据点产生的概率。该值越高,该数据越有可能是正常点,该值越低,该点越有可能是异常点。

最常见的方法是ZScore。假设数据符合正态分布,ZScore计算数据点偏离平均值的标准偏差。ZScore越大,数据偏离平均值越多,异常的概率就越高。

非参数方法不假设从训练数据中学习到的数据的先验分布。

还有其他统计方法,如时间序列中的移动平均卡尔曼滤波

利用统计方法进行异常检测非常容易理解,计算效率也非常好。然而,这种方法有一些挑战:数据点中的噪声和异常可能具有相似的统计特征,因此很难检测到它们。异常的定义可能会改变,固定的切割值可能不适用。例如,很难定义zscore的应用程序是大于3还是大于4。

用于异常检测的机器学习方法

从监督学习和非监督学习的角度来看,如果已经有大量的训练数据标记异常点,异常检测可以简单地转化为分类问题,即数据分为正常点和异常点两类。然而,在现实中,通常很难找到大量标有异常点的训练数据,因此经常需要无监督学习来检测异常。

使用数据相似性来检测异常的基本假设是,如果检测到的数据和现有数据之间的相似性很大,那么它更可能是正常数据。相似性学习主要基于距离(KNN)和密度(LOF)。

基于聚类的异常检测的基本假设是正常数据被聚集在一起,异常数据被聚集在一起。

DBSCAN是一种常见的异常检测聚类方法。关于DBSCAN算法的介绍,请参考我的博客来说明机器学习。

如上图所示,DBSCAN可以学习正常聚类的中心点a、边缘点BC和异常点n。

然而,DBSCAN对各种超级参数的设置非常敏感。虽然这种方法不需要标记异常点,但是不容易找到合适的超级参数。

支持向量机(SVM)是一种监督学习分类方法。单类支持向量机是SVM的扩展,可用于无监督异常检测。

该算法可以学习正常点和异常点之间的边界。

隔离森林是检测数据中异常值或新颖性的有效方法。这是一种基于二叉树的方法。

森林隔离的基本原则是异常值很少,与其他观测结果相差甚远。为了构建树(训练),算法从特征空中随机选择一个特征,并在最大值和最小值之间随机选择一个随机分割值。这是针对训练集中的所有观察结果。为了建造森林,整棵树被平均化为森林中的所有树。

然后,为了进行预测,它将观察值与“节点”中的分割值进行比较,该“节点”将具有两个节点子节点,在这两个子节点上将进行另一次随机比较。算法对一个实例进行的“分割”的数量被命名为“路径长度”正如预期的那样,异常值的路径长度将比其他观测值短。

使用深度学习的异常检测

既然我们知道了异常检测的基本概念和方法,我们如何使用深度学习来检测异常?

虽然神经网络的主要应用是监督学习,但它也可以用于无监督学习。这里我们需要了解自动编码器。

自编码器是一个类似于上图的网络,包括编码和解码。我们使用训练数据集来训练网络,输出目标等于输入数据。换句话说,我们已经训练了一个能够重建输入数据的深层神经网络。那么这样做有什么用呢?

我们可以看到,编码过程实际上类似于主成分分析降维过程,即在编码后,找到数据中的主要成分,利用这些主要成分可以重构原始数据,就像数据压缩和解压缩的过程一样,用较少的数据替换原始数据。对于一般自编码器的应用,训练有素的自编码器将不用于构建网络。一般来说,编码部分用于提取数据的特征并减少维数,从而实现更有效的计算。

使用自编码器,我们假设正常数据应该通过自编码器恢复,即输入和输出相同,而对于异常数据,恢复的数据不同于原始数据。基本假设是,恢复数据和输入数据之间的差异越小,正常数据的可能性就越大,而异常数据的可能性就越大。

让我们看一个使用tensorflowJS使用自编码器检测信用卡欺诈数据的例子。数据集来自卡格尔。考虑到浏览器中TensorflowJS的性能问题,我对原始数据的10,000条记录进行了采样来演示。

加载数据

该数据由kaggle处理,包括时间交易时间、金额交易金额,V1-V28为处理特征,类别表示交易类型,1为欺诈交易。

异步函数加载数据(路径)

返回等待d3.csv(路径);

}

常量数据集=等待加载数据(

" https://cdn . jsdelivr . net/GH/gang Tao/dataset @ master/CSV/credit card _ sample _ raw . CSV "

);

数据预处理

功能标准化(val,min,max)

返回(val-min)/(max-min);

}

函数准备(数据集)

const processed dataset = dataset . map(项= > 0.5)。{

const obj = { };

(让I = 1;i <。29岁;i++) {

常量键= `V $ { i }

obj键] = parseFloat(项目[键));

}

[“类”] =项目[“类”];

[“时间”] = parseFloat(项目[“时间”]);

[“金额”] =解析浮动(项目[“金额”]);

返回obj。

});

const TiME max = D3 . max(processed DataSet . map(I = > t。时间);

const TiME MIn = D3 . MIn(processed DataSet . map(I = > t。时间);

const amountMax = D3 . max(processed DataSet . map(I = > t。一.金额));

const AMOUntMIn = D3 . MIn(processed dataset . map(I = > t。一.金额));

已处理数据集。每个(项目= >个;{

item.stdTime =标准化(item。时间、最大时间、最小时间);

item.stdAmount =标准化(item。金额、最大金额、最小金额);

});

返回流程数据集;

}

常量准备数据集=准备(数据集);

在数据预处理阶段,我们对时间和数量进行标准化,使它们的值在(0-1)之间。

生成培训数据集

函数makeTrainData(数据集){

控制台.日志(数据集.长度);

const normalData = dataset.filter(项目= > t。物品。class = = " 0 ");

常量异常数据=数据集。筛选器(项目= > t。物品。class = = " 1 ");

const sliceIndex = NormaL DATa . length * 0.8;

常量正常训练数据=正常数据。切片(0,切片索引);

常量正常测试数据=正常数据.切片(切片索引+1,正常数据.长度);

控制台.日志(正常数据.长度);

常量训练数据= { x: [],y:[]};

常规培训数据。每个(项目= >项;{

常量行=[];

(让I = 1;i <。29岁;i++) {

常量键= `V $ { i }

row.push(项目[键));

}

行.按(项目[“标准金额”]);

row.push(项目[“标准时间”]);

trainData.x.push(行);

trainData.y.push(行);

});

const TestDATa = NormaL TestDATa . map(项目= > t。{

常量行=[];

(让I = 1;i <。29岁;i++) {

常量键= `V $ { i }

row.push(项目[键));

}

行.按(项目[“标准金额”]);

row.push(项目[“标准时间”]);

返回行;

});

常量测试数据=异常数据.映射(项目= > 0.5)。{

常量行=[];

(让I = 1;i <。29岁;i++) {

常量键= `V $ { i }

row.push(项目[键));

}

行.按(项目[“标准金额”]);

row.push(项目[“标准时间”]);

返回行;

});

返回[培训数据、测试数据、测试数据];

}

常量[培训数据、测试数据、测试数据] =制作培训数据(准备数据集);

我们选择了80%的正常数据进行培训,另外20%的正常交易数据和所有异常交易数据进行测试。

建立模型和培训

函数构建模型(){

有关完整的代码,请参见我的代码笔https://codepen.io/gangtao/full/yWErJX。

摘要

本文介绍了异常检测的主要方法,无论是统计方法、机器学习方法还是深度学习方法,其中主要问题是切削值或参数的设置。

对于统计方法,有必要确定事件发生的概率是否异常,百年一遇的洪水是否异常,或者千年一遇的洪水是否异常。

对于各种监督学习,我们经常缺少异常点的标记,而对于无监督学习,调整各种参数会对异常点的判断产生很大影响。

对于基于自编码器的方法,可以看出我们利用自编码器的输出和输入之间的差异来判断事件是否是异常事件。然而,用户仍然需要指定多少偏差被定义为异常。

我们希望通过数据和算法自动发现异常仍然是一个相对困难的问题。

请参考浏览器中的深入学习:TensorFlow.js (XI)时间序列预测

浏览器中的深度学习:构建推荐系统

浏览器中的深度学习:TensorFlow.js (9)训练词向量

浏览器中的深度学习:TensorFlow.js (8)生成对抗网络

浏览器中的深度学习:TensorFlow.js (7)递归神经网络

浏览器中的深度学习:张量流(6)构造卷积网络

浏览器中的深度学习:tensorflow . js(4)MNIST手写数据的识别

浏览器中的深度学习:TensorFlow.js (3)更多基本模型

浏览器中的深度学习:张量流. js (2)线性回归

浏览器中的深度学习:TensorFlow.js(一)基本概念

大家都在看

相关专题