1. 异常检测的概念
异常检测是机器学习无监督学习一个很广泛的应用,其主要目的是根据已有数据训练出一个模型,利用模型对新样本进行检测,判断新样本和训练数据是否有较大的差异。
对于已有的训练数据集 { x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) } \{x^{(1)},x^{(2)},\cdots,x^{(m)}\} {x(1),x(2),⋯,x(m)},每个样本都是由 n n n 个特征组成的特征向量,下图表示每个样本由两个特征组成的训练集,我们可以根据这些数据建立一个概率分布模型 p ( x ) p(x) p(x),对于一个新样本 x t e s t x_{test} xtest,通过 p ( x t e s t ) p(x_{test}) p(xtest) 与阈值 ϵ \epsilon ϵ 来判断 x t e s t x_{test} xtest 与训练集的相似程度:
- 若 p ( x t e s t ) < ϵ p(x_{test})<\epsilon p(xtest)<ϵ ,记 x t e s t x_{test} xtest 为异常样本
- 若 p ( x t e s t ) ≥ ϵ p(x_{test})\geq\epsilon p(xtest)≥ϵ ,记 x t e s t x_{test} xtest 为正常样本
概率函数会判断样本与数据中心区域的距离,与中心区域距离较近的点会有更高的概率,与中心距离距离较远的点会被判定为异常点。
2. 高斯分布(正态分布)
高斯分布(正态分布,Gaussian/Normal distribution) 是对数据统计特征的一种描述,对于一个变量 x x x,如果其满足高斯分布,那么记其均值为 μ \mu μ,其方差为 σ 2 \sigma^2 σ2,记为 X ∼ N ( μ , σ 2 ) X\sim N(\mu,\sigma^2) X∼N(μ,σ2)。
下图表示高斯分布的曲线,其中心点为均值 μ \mu μ, σ \sigma σ 控制曲线的宽度
下图是取不同参数时的曲线图像,高斯分布的曲线下面积是
1
1
1,而
σ
\sigma
σ 控制曲线的宽度,当
σ
\sigma
σ 取值较小时,就会使曲线更高。
确定了高斯分布中的参数
μ
\mu
μ 和
σ
\sigma
σ 后,我们就能得到具体的高斯分布曲线。对于一组服从高斯分布的数据集
{
x
(
1
)
,
x
(
2
)
,
⋯
,
x
(
m
)
}
\{x^{(1)},x^{(2)},\cdots,x^{(m)}\}
{x(1),x(2),⋯,x(m)},我们可以通过分别计算其均值和方差来得到其高斯分布函数中的参数:
μ
=
1
m
∑
i
=
1
m
x
(
i
)
σ
2
=
1
m
∑
i
=
1
m
(
x
(
i
)
−
μ
)
2
\begin{aligned} \mu = &\frac{1}{m}\sum_{i=1}^mx^{(i)} \\ \sigma^2 =& \frac{1}{m}\sum_{i=1}^m(x^{(i)}-\mu)^2 \end{aligned}
μ=σ2=m1i=1∑mx(i)m1i=1∑m(x(i)−μ)2
得到这些参数后,就能画出曲线图如下,可以发现,在样本比较密集的区域其样本的概率
p
(
x
)
p(x)
p(x) 比较大。
这样根据具体数据来估计分布中具体参数的过程就称为参数估计。
3. 异常检测算法
异常检测的目的是根据已有数据建立一个概率模型 p ( x ) p(x) p(x),使得这个模型可以对新数据是否出现异常进行判断。对于一个训练集 { x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) } \{x^{(1)},x^{(2)},\cdots,x^{(m)}\} {x(1),x(2),⋯,x(m)},每个样本 x ∈ R n x\in \mathbb{R}^n x∈Rn 是由 n n n 个特征组成的特征向量。
如果样本的每个特征是相互独立的(如用户登录网站的时间、登录地点、登录设备等特征组成的特征向量),每个特征都满足某个高斯分布,即
x
i
∼
N
(
μ
i
,
σ
i
2
)
x_i\sim N(\mu_i,\sigma_i^2)
xi∼N(μi,σi2),那么该样本的概率就可以由这几个特征出现的概率乘积表示,即:
p
(
x
)
=
p
(
x
1
;
μ
1
,
σ
1
2
)
p
(
x
2
;
μ
2
,
σ
2
2
)
p
(
x
3
;
μ
3
,
σ
3
2
)
⋯
p
(
x
n
;
μ
n
,
σ
n
2
)
=
∏
j
=
1
n
p
(
x
j
;
μ
j
,
σ
j
2
)
\begin{aligned} p(x) &=p(x_1;\mu_1,\sigma_1^2)p(x_2;\mu_2,\sigma_2^2)p(x_3;\mu_3,\sigma_3^2)\cdots p(x_n;\mu_n,\sigma_n^2) \\ & = \prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2) \end{aligned}
p(x)=p(x1;μ1,σ12)p(x2;μ2,σ22)p(x3;μ3,σ32)⋯p(xn;μn,σn2)=j=1∏np(xj;μj,σj2)
p ( x ) p(x) p(x) 也称为概率密度函数,其表示样本 x x x 出现的概率,确定密度函数中的参数 μ i 、 σ i 2 \mu_i、\sigma_i^2 μi、σi2 的过程也称为 密度估计。
知道了怎么确定一个样本出现的概率后,我们需要通过密度估计的方式求出所有的参数,所以整个异常检测的过程为:
- 选择可以描述数据集一般特征的特征 x i x_i xi
- 使用如下方法计算所有训练数据集中每个特征对应的参数
μ
j
、
σ
j
2
\mu_j、\sigma_j^2
μj、σj2
μ j = 1 m ∑ i = 1 m x j ( i ) σ j 2 = 1 m ∑ i = 1 m ( x j ( i ) − μ j ) 2 \begin{aligned} \mu_j &= \frac{1}{m}\sum_{i=1}^mx_j^{(i)} \\ \sigma_j^2 &= \frac{1}{m}\sum_{i=1}^m(x_j^{(i)}-\mu_j)^2 \end{aligned} μjσj2=m1i=1∑mxj(i)=m1i=1∑m(xj(i)−μj)2 - 对于一个新给出的样本,通过如下方式计算样本出现的概率,并与阈值
ϵ
\epsilon
ϵ 比较,判断样本是否出现异常
p ( x ) = ∏ j = 1 n p ( x j ; μ j , σ j 2 ) = ∏ j = 1 n 1 2 π e − ( x j − μ j ) 2 2 σ j 2 p(x)= \prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2)=\prod_{j=1}^n\frac{1}{\sqrt{2\pi}}e^{-\frac{(x_j-\mu_j)^2}{2\sigma_j^2}} p(x)=j=1∏np(xj;μj,σj2)=j=1∏n2π1e−2σj2(xj−μj)2
对于如下的数据集:
通过计算可以得到:
μ
1
=
5
,
σ
1
=
2
μ
2
=
3
,
σ
2
=
1
\begin{aligned} \mu_1 = 5,\sigma_1=2\\ \mu_2=3,\sigma_2=1 \end{aligned}
μ1=5,σ1=2μ2=3,σ2=1
可以分别得到如下图所示的概率分布曲线:
还可以表示为如下所示的曲线:
可以看到,随着数据点偏离样本中心,其概率
p
(
x
)
p(x)
p(x) 会逐渐变小,而
p
(
x
)
<
ϵ
p(x)<\epsilon
p(x)<ϵ 也就对应于图中概率小于
ϵ
\epsilon
ϵ 的点,根据
ϵ
\epsilon
ϵ 可以在原数据集中确定一条判断异常的边界,如下所示,在边界外的点都会被判断为异常点。
4. 异常检测算法的评估
很多时候我们要比较两个异常检测算法哪个会有更好的性能,比如判断特征向量中加入某个特征会不会对模型有更好的影响,所以我们就需要一个具体的方法来评估两个异常算法的好坏。
对异常检测算法进行评估的主要方式是通过对一些已有标签的数据进行判断,从而得到一些性能指标来衡量算法的有效性。假设我们有一训练集 { x ( 1 ) , x ( 2 ) , ⋯ , x ( m ) } \{x^{(1)},x^{(2)},\cdots,x^{(m)}\} {x(1),x(2),⋯,x(m)},其中可能包含正常样本和一少部分异常样本,我们直接通过这些样本计算出概率模型 p ( x ) p(x) p(x),之后根据有标签的交叉验证集 { ( x c v ( 1 ) , y c v ( 1 ) ) , ( x c v ( 2 ) , y c v ( 2 ) ) , ⋯ , ( x c v ( m c v ) , y c v ( m c v ) ) } \{(x_{cv}^{(1)},y_{cv}^{(1)}),(x_{cv}^{(2)},y_{cv}^{(2)}),\cdots,(x_{cv}^{(m_{cv})},y_{cv}^{(m_{cv})})\} {(xcv(1),ycv(1)),(xcv(2),ycv(2)),⋯,(xcv(mcv),ycv(mcv))} 和测试集 { ( x t e s t ( 1 ) , y t e s t ( 1 ) ) , ( x t e s t ( 2 ) , y t e s t ( 2 ) ) , ⋯ , ( x t e s t ( m t e s t ) , y t e s t ( m t e s t ) ) } \{(x_{test}^{(1)},y_{test}^{(1)}),(x_{test}^{(2)},y_{test}^{(2)}),\cdots,(x_{test}^{(m_{test})},y_{test}^{(m_{test})})\} {(xtest(1),ytest(1)),(xtest(2),ytest(2)),⋯,(xtest(mtest),ytest(mtest))} 来对概率模型进行评估。
如果有 10000 10000 10000 个正常的样本, 20 20 20 个异常的样本(实际中,异常样本的数量一般只占很少一部分),我们可以选择 6000 6000 6000 个正常样本作为训练集, 2000 2000 2000 个正常个样本( y = 0 y=0 y=0)加 10 10 10 个异常样本( y = 1 y=1 y=1)作为交叉验证集,其余的 2000 2000 2000 个正常个样本( y = 0 y=0 y=0)和 10 10 10 个异常样本( y = 1 y=1 y=1)作为测试集。
当我们根据训练集样本得到概率函数 p ( x ) p(x) p(x) 后,使用交叉验证集和测试集进行预测:
- 若 p ( x ) < ϵ p(x)<\epsilon p(x)<ϵ ,记预测结果为异常
- 若 p ( x ) ≥ ϵ p(x)\geq\epsilon p(x)≥ϵ ,记预测结果为正常
由于交叉验证集和测试集都是有真实标签的,而正负样本的比例又是非常失衡的,所以我们可以使用对不平衡数据集训练模型时的评估方法:
- 首先计算混淆矩阵,得到 True positive、false positive、false negative、true negative
- 根据混淆矩阵计算 Precision/Recall 曲线
- 计算 F 1 − s c o r e F_1-score F1−score
我们还可以根据验证集选择不同大小的 ϵ \epsilon ϵ,当某个 ϵ \epsilon ϵ 使得 F 1 − s c o r e F_1-score F1−score 最大时,其就是最佳的选择。
5. 异常检测与监督学习
在异常检测的算法评估中,我们是对有标签的数据执行异常检测的算法,那么对于有标签的数据,我们具体应该选择异常检测算法还是监督学习算法呢?
-
异常检测算法
异常检测算法一般用于正负样本数量差距较大的情况,对于工厂零件的异常检测来说,一般来说,异常零件的数目是很少的,在这种情况下我们不能根据少量的异常零件来学习得到普遍的特征,这个时候我们可以选择对正常零件建立概率模型,根据新的零件是否满足该概率模型来进行异常的检测。
异常检测还可以用于对未知异常的检测,我们对正常的数据建立概率模型,那么当有一些未知的原因导致数据出现从未见过的异常时,会因为异常数据和正常数据的概率分布不同而被检测出来。
-
监督学习算法
监督学习算法一般用于正负类型的样本数目比较近似的情况下,这样我们就有足够的样本来学习正例样本的特征分布,从而获得更加准确的判断。
6. 特征的设计与选择
6.1 非高斯分布的特征
在异常检测中是使用高斯分布对特征进行建模,通常情况下,即使数据不满足高斯分布,我们仍然可以得到正确的结果,但是通常会将数据变换为高斯分布。
下图表示某个特征的直方图分布,其本身不满足高斯分布的曲线,通过使用 log ( x ) \log(x) log(x) 对特征进行变换,就将其变换到满足高斯分布。
通常对数据进行变换的方式包括:
- log ( x + c ) \log(x+c) log(x+c) 其中 c c c 表示一个常数
- x c x^c xc 其中 0 < c < 1 0\lt c\lt 1 0<c<1
其中的参数 c c c 可以根据情况选择。
6.2 异常检测中特征的选择
通常对于一个样本,可能存在很多特征,我们构建的特征可能并不能很好的对异常样本进行筛选,如下图所示:
对于只有一个特征
x
1
x_1
x1 的数据集构建的异常检测系统可能会检测不出来下图中的绿色异常样本点,这个时候我们可以观察该异常样本与其他正常的样本有哪些特征不同,这样我们再使用这些特征构建新的特征
x
2
x_2
x2,如下所示,这样我们就能实现对异常样本的检测了。
除此之外,我们还可以使用已有特征构建新特征的方法实现异常检测,如在数据中心的异常检测系统中,CPU 使用率和网络流量通常是成正比的,因为网络流量越大说明 CPU 要处理的数据越多,但是 CPU 还可能因为其他原因导致使用率较高,如果我们只是通过单一的特征可能并不能检测出因其他原因导致的异常,这时我们可以构建新的特征 C P U 使 用 率 网 络 流 量 \frac{CPU使用率}{网络流量} 网络流量CPU使用率,这样如果是因为其他原因导致 CPU 使用率过高就能通过这个新的特征检测出来。
7. 多元高斯分布
对于如下左图所示的数据,两个特征
x
1
x_1
x1 与
x
2
x_2
x2 有某种相互的关系,分散在一个椭圆形的边界中,但是对于图中的绿色样本,将其分别对应到每个特征得到的高斯分布曲线中,如下右图所示,可以发现在两个特征的高斯分布图中对应的概率都没有很小,所以这个样本不会被检测为异常样本。
为了解决这个问题,我们使用多元高斯分布(multivariate gaussian/normal distribution)。对于一个样本
x
∈
R
n
x\in\mathbb{R}^n
x∈Rn ,这是包含有
n
n
n 个特征的向量,我们并不为每个特征构建一个分布,而是通过多元高斯分布为这多个特征建立一个统一的模型
p
(
x
)
p(x)
p(x):
p
(
x
;
μ
,
Σ
)
=
1
(
2
π
)
n
2
∣
Σ
∣
1
2
e
−
1
2
(
x
−
μ
)
T
Σ
−
1
(
x
−
μ
)
p(x;\mu,\Sigma)=\frac{1}{(2\pi)^{\frac{n}{2}}|\Sigma|^{\frac{1}{2}}}e^{-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)}
p(x;μ,Σ)=(2π)2n∣Σ∣211e−21(x−μ)TΣ−1(x−μ)
其中 μ ∈ R n \mu\in \mathbb{R}^n μ∈Rn 是均值向量, Σ ∈ R n × n \Sigma\in\mathbb{R}^{n\times n} Σ∈Rn×n 是一个 n × n n \times n n×n 的协方差矩阵。通过上式,我们就将多个特征融合到一个等式内了,这样就可以根据多个特征得到一个结果。
Σ \Sigma Σ 是协方差矩阵,其衡量特征 x 1 x_1 x1 和 x 2 x_2 x2 的变化情况,我们选择不同大小的 μ \mu μ 和 Σ \Sigma Σ 值会得到不同的概率模型,通过改变其中的参数,就可以描述特征之间的的正相关或负相关,如下展示了不同的参数对结果的影响。
-
下图展示了当增大或减小 Σ \Sigma Σ 对角线元素值时,得到的概率分布。上层表示概率分布的图像,下面表示对应的等高线图像,颜色越红表示概率越大。可以看到如果减小 Σ \Sigma Σ 中元素的值,会让概率区域变小,但是高度更高;反之,曲线的区域会变大,高度更低。
-
因为 Σ \Sigma Σ 中对角线的值表示对应特征的离散情况,当减小 Σ \Sigma Σ 对角线中的某个值时,会让对应的特征的分布更紧凑,从而让其范围减小,如下中间所示。反之会使范围增大。
-
这里展示了对对角线的第二个元素增大或缩小时的效果。
-
这里展示了对 Σ \Sigma Σ 副对角线元素改变时,概率分布的变化情况。
-
当副对角线的元素为负时,概率分布的变化如下。
-
由于 μ \mu μ 中的元素表示对应位置的均值,所以如下图所示,当改变 μ \mu μ 的值时候,会使特征分布的中心发生偏移,移动到新的位置。
8. 利用多元高斯分布进行异常检测
这里将介绍怎么将上面提到的多元高斯分布应用到实际的异常检测中,多元高斯分布的概率分布表达式如下所示:
p
(
x
;
μ
,
Σ
)
=
1
(
2
π
)
n
2
∣
Σ
∣
1
2
e
−
1
2
(
x
−
μ
)
T
Σ
−
1
(
x
−
μ
)
p(x;\mu,\Sigma)=\frac{1}{(2\pi)^{\frac{n}{2}}|\Sigma|^{\frac{1}{2}}}e^{-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)}
p(x;μ,Σ)=(2π)2n∣Σ∣211e−21(x−μ)TΣ−1(x−μ)
其中包含两个参数
μ
∈
R
n
\mu\in\mathbb{R}^n
μ∈Rn 和
Σ
∈
R
n
×
n
\Sigma\in\mathbb{R}^{n\times n}
Σ∈Rn×n ,为了使用上式进行异常检测,首先要拟合这两个参数,对于
μ
\mu
μ:
μ
=
1
m
∑
i
=
1
m
x
(
i
)
\mu = \frac{1}{m}\sum_{i=1}^{m}x^{(i)}
μ=m1i=1∑mx(i)
其表示求所有样本特征向量的均值。对于
Σ
\Sigma
Σ:
Σ
=
1
m
∑
i
=
1
m
(
x
(
i
)
−
μ
)
(
x
(
i
)
−
μ
)
T
\Sigma = \frac{1}{m}\sum_{i=1}^m(x^{(i)}-\mu)(x^{(i)}-\mu)^T
Σ=m1i=1∑m(x(i)−μ)(x(i)−μ)T
这和我们在 PCA 中求解协方差矩阵类似。
在得到这两个参数后,就能通过上面的概率分布表达式计算新样本的概率 p ( x ) p(x) p(x),根据 p ( x ) < ϵ p(x)\lt \epsilon p(x)<ϵ 确定是否要将样本划分为异常。
在上面我们对于多特征的数据进行处理时使用的是如下的概率分布函数:
p
(
x
)
=
p
(
x
1
;
μ
1
,
σ
1
2
)
p
(
x
2
;
μ
2
,
σ
2
2
)
p
(
x
3
;
μ
3
,
σ
3
2
)
⋯
p
(
x
n
;
μ
n
,
σ
n
2
)
=
∏
j
=
1
n
p
(
x
j
;
μ
j
,
σ
j
2
)
\begin{aligned} p(x) &=p(x_1;\mu_1,\sigma_1^2)p(x_2;\mu_2,\sigma_2^2)p(x_3;\mu_3,\sigma_3^2)\cdots p(x_n;\mu_n,\sigma_n^2) \\ & = \prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2) \end{aligned}
p(x)=p(x1;μ1,σ12)p(x2;μ2,σ22)p(x3;μ3,σ32)⋯p(xn;μn,σn2)=j=1∏np(xj;μj,σj2)
这个函数其实就是多元高斯分布的一种特例,在这种情况下,得到的概率分布的图像的长轴和短轴与坐标系的轴是平行的,如下所示:
而从多元高斯分布不同参数的曲线图也可以得到结论,原高斯分布函数对应于多元高斯分布中的一个特例,而满足上图所示图像的多元高斯分布,其协方差矩阵
Σ
\Sigma
Σ 是一个对角矩阵,即
Σ
=
[
σ
1
2
σ
2
2
⋱
σ
n
2
]
\Sigma = \left[ \begin{matrix} \sigma_1^2 & & & \\ & \sigma_2^2 & & \\ & & \ddots & \\ &&& \sigma_n^2 \end{matrix}\right]
Σ=⎣⎢⎢⎡σ12σ22⋱σn2⎦⎥⎥⎤
其中的参数对应于下式中的参数:
p
(
x
)
=
p
(
x
1
;
μ
1
,
σ
1
2
)
p
(
x
2
;
μ
2
,
σ
2
2
)
p
(
x
3
;
μ
3
,
σ
3
2
)
⋯
p
(
x
n
;
μ
n
,
σ
n
2
)
=
∏
j
=
1
n
p
(
x
j
;
μ
j
,
σ
j
2
)
\begin{aligned} p(x) &=p(x_1;\mu_1,\sigma_1^2)p(x_2;\mu_2,\sigma_2^2)p(x_3;\mu_3,\sigma_3^2)\cdots p(x_n;\mu_n,\sigma_n^2) \\ & = \prod_{j=1}^n p(x_j;\mu_j,\sigma_j^2) \end{aligned}
p(x)=p(x1;μ1,σ12)p(x2;μ2,σ22)p(x3;μ3,σ32)⋯p(xn;μn,σn2)=j=1∏np(xj;μj,σj2)
因为这种特殊形式的多元高斯分布方程的轮廓是轴对齐的,所以不能对不同特征之间的关系进行建模,这时就需要使用一般形式的多元高斯分布。
那么我们应该怎样对两者进行选择呢?
-
一般的高斯分布模型 p ( x ) = p ( x 1 ; μ 1 , σ 1 2 ) p ( x 2 ; μ 2 , σ 2 2 ) p ( x 3 ; μ 3 , σ 3 2 ) ⋯ p ( x n ; μ n , σ n 2 ) p(x) =p(x_1;\mu_1,\sigma_1^2)p(x_2;\mu_2,\sigma_2^2)p(x_3;\mu_3,\sigma_3^2)\cdots p(x_n;\mu_n,\sigma_n^2) p(x)=p(x1;μ1,σ12)p(x2;μ2,σ22)p(x3;μ3,σ32)⋯p(xn;μn,σn2)
通常情况下,我们都使用这种一般的高斯分布模型,虽然其不能对特征之间的关系建模,但是我们可以对有关系的特征进行处理,构造出能够表示两个特征之间关系的特征,这样就能将特征之间的关系加入模型中。如上面我们构造的新特征 C P U 使 用 率 网 络 流 量 \frac{CPU使用率}{网络流量} 网络流量CPU使用率。
这种一般模型还有一个特点是计算的时间复杂度比较低,并且就算数据集中的样本数量 m m m 小于样本的特征个数 n n n 时,仍然可以正常工作。
-
多元高斯分布模型 p ( x ; μ , Σ ) = 1 ( 2 π ) n 2 ∣ Σ ∣ 1 2 e − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) p(x;\mu,\Sigma)=\frac{1}{(2\pi)^{\frac{n}{2}}|\Sigma|^{\frac{1}{2}}}e^{-\frac{1}{2}(x-\mu)^T\Sigma^{-1}(x-\mu)} p(x;μ,Σ)=(2π)2n∣Σ∣211e−21(x−μ)TΣ−1(x−μ)
多元高斯分布的主要特点是可以自动地获取特征之间的关系,但是由于其中包含了计算协方差矩阵的求逆操作 Σ − 1 \Sigma^{-1} Σ−1 ,所以当特征的维数 n n n 比较大时会造成计算复杂度过大。
多元高斯分布还有一个缺点是当样本数量 m m m 比特征数量 n n n 小时,会使协方差矩阵 Σ \Sigma Σ 的行列式为 0 0 0 这时就不能计算 Σ − 1 \Sigma^{-1} Σ−1,所以在使用多元高斯分布时,我们一般要保证 m ≫ n m \gg n m≫n。