一、正态分布/高斯分布
异常检测假设特征符合正太分布(Normal Distribution)/高斯分布(Gaussian Distribution):
如果,我们认为变量x服从正态分布,则其可以表示为:
x
∼
N
(
μ
,
σ
2
)
x \sim N\left(\mu, \sigma^{2}\right)
x∼N(μ,σ2)
服从正态分布的函数,其有两个重要指标:期望:
μ
,
方
差
:
σ
2
\mu, 方差: \sigma^{2}
μ,方差:σ2
其中:
μ
=
1
m
Σ
i
=
1
m
x
(
i
)
,
σ
2
=
1
m
Σ
i
=
1
m
(
x
(
i
)
−
μ
)
2
\mu=\frac{1}{m} \Sigma_{i=1}^{m} x^{(i)}, \sigma^{2}=\frac{1}{m} \Sigma_{i=1}^{m}\left(x^{(i)}-\mu\right)^{2}
μ=m1Σi=1mx(i),σ2=m1Σi=1m(x(i)−μ)2
整个分布的概率密度函数为:
p
(
x
,
μ
,
σ
2
)
=
1
2
π
σ
exp
(
−
(
x
−
μ
)
2
2
σ
2
)
p\left(x, \mu, \sigma^{2}\right)=\frac{1}{\sqrt{2 \pi} \sigma} \exp \left(-\frac{(x-\mu)^{2}}{2 \sigma^{2}}\right)
p(x,μ,σ2)=2πσ1exp(−2σ2(x−μ)2)
整个概率密度函数的累加和为1,即表示100%
二、异常检测算法
假设,我们有一组无标签(没有y)的训练集
x
(
1
)
,
x
(
2
)
,
…
,
x
(
m
)
x^{(1)}, x^{(2)}, \ldots, x^{(m)}
x(1),x(2),…,x(m),这些训练集有n个特征,我们将用这些数据利用正太分布,构造出异常检测算法。
其实,很简单,无非是算出训练集所有样本在每个特征上的的期望和方差,然后所有的概率相乘,即可得到总体概率密度函数。我们根据得到的p(x)和设定的判断边界
ε
\varepsilon
ε 即可对未知样本经行异常检测,这便是一个简单的异常检测算法。具体如下:
对于给定的数据集
x
(
1
)
,
x
(
2
)
,
…
,
x
(
m
)
x^{(1)}, x^{(2)}, \ldots, x^{(m)}
x(1),x(2),…,x(m),我们要针对给定的每一个特征计算
μ
和
σ
2
\mu和\sigma^{2}
μ和σ2的估计值
μ
j
=
1
m
∑
i
=
1
m
x
j
(
i
)
\mu_{j}=\frac{1}{m} \sum_{i=1}^{m} x_{j}^{(i)}
μj=m1i=1∑mxj(i)
σ
j
2
=
1
m
∑
i
=
1
m
(
x
j
(
i
)
−
μ
j
)
2
\sigma_{j}^{2}=\frac{1}{m} \sum_{i=1}^{m}\left(x_{j}^{(i)}-\mu_{j}\right)^{2}
σj2=m1i=1∑m(xj(i)−μj)2
一旦我们获得了平均值和方差的估计值,给定新的一个训练实例,根据模型计算
p
(
x
)
p(x)
p(x):
p
(
x
)
=
∏
j
=
1
n
p
(
x
j
;
μ
j
,
σ
j
2
)
=
∏
j
=
1
1
1
2
π
σ
j
exp
(
−
(
x
j
−
μ
j
)
2
2
σ
j
2
)
p(x)=\prod_{j=1}^{n} p\left(x_{j} ; \mu_{j}, \sigma_{j}^{2}\right)=\prod_{j=1}^{1} \frac{1}{\sqrt{2 \pi} \sigma_{j}} \exp \left(-\frac{\left(x_{j}-\mu_{j}\right)^{2}}{2 \sigma_{j}^{2}}\right)
p(x)=j=1∏np(xj;μj,σj2)=j=1∏12πσj1exp(−2σj2(xj−μj)2)
当
p
(
x
)
<
ε
p(x)<\varepsilon
p(x)<ε时,为异常。
我们有两个特征x1,x2,左上角是训练集中所有的样本点(红色)和特征关系图;右上角是单个特征的概率密度分布图,左下角是总体的分布图。
我们通过概率密度分布可以对新的样本点经行异常检测了,此处设定的
ε
\varepsilon
ε 为0.02(判定边界)。经过计算,可以发现x_test1样本点的概率 > 0.02,正常;x_test1概率 < 0.02,故被判断为异常。
三、异常检测系统
异常检测系统是基于异常检测算法开发的,其不仅包含异常检测算法,还增加了开发和评价过程,主要是在真实环境下,对样本的划分(训练集、交叉验证集、测试集)、对系统的评价等。
异常检测算法是一个非监督学习算法,意味着我们无法根据结果变量y的值来告诉我们数据是否真的是异常的。我们需要另一种方法来帮助检验算法是否有效。当我们开发一个异常检测系统时,我们从带标记(异常或正常)的数据着手,我们从其中选择一部分正常数据用于构建训练集,然后用剩下的正常数据和异常数据混合的数据构成交叉检验集和测试集。
例如:我们有 10000 台正常引擎的数据,有20 台异常引擎的数据。 我们这样分配数据:
6000 台正常引擎的数据作为训练集
2000 台正常引擎和 10 台异常引擎的数据作为交叉检验集
2000 台正常引擎和 10 台异常引擎的数据作为测试集
具体的评价方法如下:
1.根据测试集数据,我们估计特征的平均值和方差并构建p(x)函数
2.对交叉检验集,我们尝试使用不同的值作为阀值,并预测数据是否异常,根据 F1 值或者查准率与查全率的比例来选择
3.选出
ε
\varepsilon
ε 后,针对测试集进行预测,计算异常检验系统的F1值,或者查准率与查全率之比。
四、异常检测与监督学习对比
异常检测 | 监督学习 |
---|---|
非常少量的正向类(异常数据y=1),大量的负向类(y=0) | 同时有大量的正向类和负向类 |
许多不同种类的异常,非常难。根据非常 少量的正向类数据来训练算法 | 有足够多的正向类实例,足够用于训练 算法,未来遇到的正向类实例可能与训练集中的非常近似。 |
未来遇到的异常可能与已掌握的异常、非常的不同。 | |
例如: 欺诈行为检测 生产(例如飞机引擎)检测数据中心的计算机运行状况 | 例如:邮件过滤器 天气预报 肿瘤分类 |
五、特征选择
5.1 数据转换
在选择特征之前,我们要尽量确保数据是基本符合高斯分布的,否则我们需要将其转化成近似高斯分布的形态。例如使用对数函数
x
=
log
(
x
+
c
)
x=\log (x+c)
x=log(x+c),其中c为非负数,范围在0-1之间。在 python 中,通常用 np.log1p()函数。
5.2 误差分析
误差分析的目的在于:
从已有的模型和特征中开始跑样本,通过对预测结果中判断错误的数据(误差)进行分析,从而发现和挑选更适合的特征,从而改进模型。
我们通过p(x)来判断一个样本是正常还是异常,且通常情况下,**我们希望正常样本的p(x)尽量大,异常样本的p(x)足够小,**但这往往就是通常会出问题的地方,即当一个实际上是异常的样本点,经过异常检测系统判断后p(x)确足够大,即异常检测系统判断失效,导致判断错误。
原模型有一个特征x1,经过异常检测算法拟合出来的曲线如上左图,这时候有一个异常样本,用该模型检测时,确发现其x值在正常区间,如上左图中绿点所示,所以我们得到一个信息:该异常检测模型不够完善,可能是由于特征x1不够,不能覆盖样本的总体特征情况。
此时,我们即可构造出新特征,即采用x1和x2两个特征,再重新应用异常检测算法训练模型,新训练的样本特征分布图如上右图,通过这个新的异常检测系统,我们可以成功预测出异常点。