机器学习 吴恩达 第十四章 笔记
十四、异常检测(Anomaly Detection)
14.1 问题的动机
在接下来的小节里,我将大家介绍异常检测(Anomaly detection)问题.这是机器学习算法的一个常见应用.这种算法的一个有趣之处在于:它虽然主要用于非监督学习问题,但从某些角度看,它又类似于一些监督学习问题.
什么是异常检测呢?为了解释这个概念,让我举一个例子吧:
假想你是一个飞机引擎制造商,当你生产的飞机引擎从生产线上流出时,你需要进行QA(质量控制测试),而作为这个测试的一部分,你测量了飞机引擎的一些特征变量,比如引擎运转时产生的热量,或者引擎的振动等等.
这样一来,你就有了一个数据集,从\(x_1\)到\(x_m\),如果你生产了\(m\)个引擎的话,你将这些数据绘制成图表,看起来就是这个样子:
这样,异常检测问题可以定义如下:我们假设后来有一天,你有一个新的飞机引擎从生产线上流出,而你的新飞机引擎有特征变量\(x_{test}\).所谓的异常检测问题就是:我们希望知道这个新的飞机引擎是否有某种异常,或者说,我们希望判断这个引擎是否需要进一步测试.因为,如果它看起来像一个正常的引擎,那么我们可以直接将它运送到客户那里,而不需要进一步的测试.
给定数据集\(x^{(1)},x^{(2)},...,x^{(m)}\).我们假使数据集是正常的,我们希望知道新的数据\(x_{test}\)是不是异常的,即这个测试数据不属于该组数据的几率如何.我们所构建的模型应该能根据该测试数据的位置告诉我们其属于一组数据的可能性\(p(x)\).
上图中,在蓝色圈内的数据属于该组数据的可能性较高,而越是偏远的数据,其属于该组数据的可能性就越低.这种方法称为密度估计,表达如下:
异常检测还有一个应用是欺诈检测.
模型\(p(x)\)为我们其属于一组数据的可能性,通过\(p(x) < \varepsilon\)检测非正常用户.
异常检测主要用来识别欺骗.例如在线采集而来的有关用户的数据,一个特征向量中可能会包含如:用户多久登录一次,访问过的页面,在论坛发布的帖子数量,甚至是打字速度等.尝试根据这些特征构建一个模型,可以用这个模型来识别那些不符合该模式的用户.
再一个例子是检测一个数据中心,特征可能包含:内存使用情况,被访问的磁盘数量,CPU的负载,网络的通信量等.根据这些特征可以构建一个模型,用来判断某些计算机是不是有可能出错了.
14.2 高斯分布
在本节中,我将介绍高斯分布也称为正态分布.回顾高斯分布的基本知识.
假设\(x\)是一个实数的随机变量,它符合高斯分布\(x\)~\(N(\mu,\sigma^2)\),第一个参数\(\mu\)是均值,第二个是方差.
\(\mu\)是顶点在x轴位置,\(\sigma\)是峰的宽度(标准差).上图的曲线是\(X\)取不同值的概率.其概率密度函数为\(p(x,\mu,\sigma^2) = \frac1{\sqrt{2Π}\sigma}exp(-\frac{(x-\mu)^2}{2\sigma^2})\)
下面是一些高斯分布的例子:
接下来再讨论一下参数估计的问题,假设我们有数据集\(x^{(1)},x^{(2)},...,x^{(m)}\).我们假设它符合高斯分布,那么我们就需要知道\(\mu\)和\(\sigma\)的值.参数估计就是给定数据集\(x\),我们希望能找到\(\mu\)和\(\sigma^2\)的值.下图有求解参数值的方法.
注:机器学习中对于方差我们通常只除以\(m\)而非统计学中的\((m-1)\).这里顺便提一下,在实际使用中,到底是选择使用还是\(\frac1m\)还是\(\frac1{m-1}\)其实区别很小,只要你有一个还算大的训练集,在机器学习领域大部分人更习惯使用\(\frac1m\)这个版本的公式。这两个版本的公式在理论特性和数学特性上稍有不同,但是在实际使用中,他们的区别甚小,几乎可以忽略不计.但是如果样本不多,最好使用\(\frac1{m-1}\)
14.3 异常监测算法
假定我们有\(m\)个样本无标签训练集,每个样本都是\(R^n\).我们构建异常监测算法就是要用数据集建立起概率模型\(p(x)\).
异常监测算法:
- 对于给定的数据集\(x^{(1)},x^{(2)},...,x^{(m)}\)(一般都是选可能出现异常的特征),我们要针对每一个特征计算\(\mu\)和\(\sigma^2\)的估计值.
- 一旦我们获得了平均值和方差的估计值,给定新的一个训练实例,根据模型计算\(p(x)\).
- 当\(p(x) < \varepsilon\)时,为异常.
下面是异常监测的一个例子,一个由两个特征的训练集,以及特征的分布情况(\(x_1\)的均值估计为5,标准差估计为\(2\))
下面的三维图表表示的是密度估计函数\(p(x)\),\(z\)轴为根据两个特征的值所估计\(p(x)\)值.
我们选择一个\(\varepsilon\),将\(p(x) = \varepsilon\)作为我们的判定边界,当\(p(x) > \varepsilon\)时预测数据为正常数据,否则为异常.
14.4 开发和评价一个异常检测系统
在本节,我们介绍一个异常监测的应用来解决实际问题.
异常检测算法是一个非监督学习算法,意味着我们无法根据结果变量\(y\)的值来告诉我们数据是否真的是异常的.我们需要另一种方法来帮助检验算法是否有效.当我们开发一个异常检测系统时,我们从带标记(异常或正常)的数据着手,我们从其中选择一部分正常数据(包含一部分非正常数据也可以)用于构建训练集,然后用剩下的正常数据和异常数据混合的数据构成交叉检验集和测试集.
举一个具体的例子,例如:我们有10000台正常引擎的数据,有20台异常引擎的数据.我们这样分配数据(60%、20%、20%):
-
6000台正常引擎的数据作为训练集拟合概率模型\(p(x)\)
-
2000台正常引擎和10台异常引擎的数据作为交叉检验集
-
2000台正常引擎和10台异常引擎的数据作为测试集
那么如何评价一个异常监测算法呢: -
根据训练集数据,我们估计特征的平均值和方差并构建\(p(x)\).
-
对交叉检验集,我们尝试使用不同的值\(\varepsilon\)作为阀值,并预测数据是否异常,根据F1值或者查准率与查全率的比例来选择\(\varepsilon\)
-
选出\(\varepsilon\)后,针对测试集进行预测,计算异常检验系统的\(F1\)值,或者查准率与查全率之比.
14.5 异常检测与监督学习对比
之前我们构建的异常检测系统也使用了带标记的数据,与监督学习有些相似,下面的对比有助于选择采用监督学习还是异常检测:
异常检测问题的非正常样本很少(0-20的情况很常见),而正常样本很多.不一定看表,主要看正常与非正常数据.
14.6 选择特征
对于异常检测算法,我们使用的特征是至关重要的,下面谈谈如何选择特征.
异常检测假设特征符合高斯分布,如果数据的分布不是高斯分布,异常检测算法也能够工作,但是最好还是将数据转换成高斯分布.例如使用对数函数:$ x=log(x+c) \(,其中\)c\(为非负常数.或者\)x = x^c\(,\)c\(为0-1之间的一个分数等方法.(编者注:在python中,通常用`np.log1p()`函数,\)log1p\(就是\)log(x+1)\(,可以避免出现负数结果,反向函数就是`np.expm1()`).
  第二个问题我们要讨论的是如何得到异常检测算法的特征.
  方法和监督学习问题的误差分析很像.训练出的算法在交叉验证集上拟合,看是否有可以帮助算法的特征.
  一个常见的问题是一些异常的数据可能也会有较高的\)p(x)$值,因而被算法认为是正常的.这种情况下误差分析能够帮助我们,我们可以分析那些被算法错误预测为正常的数据,观察能否找出一些问题.我们可能能从问题中发现我们需要增加一些新的特征,增加这些新特征后获得的新算法能够帮助我们更好地进行异常检测。
一般而言,我们选择特征时,不会选择那些非常大或者非常小的特征.