异常值检测与预测
前言
异常检测的场景很多,例如硬件的故障检测、流量的异常点的检测等场景。这篇博客我们针对的是时间序列的异常检测。时间序列异常的检测算法有很多,业界比较流行的比如普通的统计学习方法–3σ原则,它利用检测点偏移量来检测出异常。比如普通的回归方法,用曲线拟合方法来检测新的节点和拟合曲线的偏离程度,甚至有人讲CNN和RNN技术应用到异常点的检测。
通过普通的阈值来检测流量异常的方法效果比较差,本篇文章提出了一种新的检测算法,下面将重点介绍我们在实践过程中的经验
时间序列的经验:
对于时间序列(是指将同一统计指标的数值按其发生的时间先后顺序排列而成的数列)来说,T时刻的数值对于T-1时刻有很强的依赖性。比如某个游乐园人数在8:00很多,在8:01时刻的人数很多的概率是很大的,但是如果07:01时刻人数对于8:01时刻影响不是很大。
基于曲线拟合的检测方法
针对最近时间窗口内的数据遵循某种趋势的现象,我们使用一条曲线对该趋势进行拟合,如果新的数据打破了这种趋势,使曲线变得不平滑,则该点就出现了异常。
1.曲线拟合的方法:
回归 移动平均 指数权重移动平均
2.统计方法
(1)基于同期数据的监测方式
静态阈值
动态阈值
业界关于动态阈值设置的方法有很多,今天介绍一种针对我们lvs流量异常检测的阈值设置方法。通常阈值设置方法会参考过去一段时间内的均值、最大值以及最小值,我们也同样应用此方法。取过去一段时间(比如T窗口)的平均值、最大值以及最小值,然后取max-avg和avg-min的最小值。之所以取最小值的原因是让筛选条件设置的宽松一些,让更多的值通过此条件,减少一些漏报的事件。
优点:
反映出周期性;
可以确保发现大的故障,出了告警一定是大问题;
缺点:
依赖周期性的历史数据,计算量大,而且无法对新接入的曲线告警;
非常不敏感,小波动无法发现;
(2)及与同期振幅的检测方式
a
m
p
l
i
t
u
d
e
=
max
[
∣
x
i
(
t
)
−
x
i
(
t
−
1
)
x
i
(
t
−
1
)
∣
]
,
x
=
1...
n
amplitude\,\,=\,\,\max \left[ \left| \frac{x_i\left( t \right) -x_i\left( t-1 \right)}{x_i\left( t-1 \right)} \right| \right] ,x=\,\,1...n
amplitude=max[
xi(t−1)xi(t)−xi(t−1)
],x=1...n
使用n个振幅的绝对值作为标准,如果m时刻的振幅({m(t) – m(t-1)]/m(t-1))大于amplitudethreshold并且m时刻的振幅大于0,则我们认为该时刻发生突增,而如果m时刻的振幅大于amplitudethreshold并且m时刻的振幅小于0,则认为该时刻发生突减。
优点:
比绝对值要敏感;
利用了时间周期性,规避了业务曲线自身的周期性陡降;
缺点:
要求原曲线是光滑的;
周期性陡降的时间点必须重合,否则误警;
按百分比计算容易在低峰时期误警;
陡降不一定代表故障,由上层服务波动引起的冲高再回落的情况时有发生;
3.基于环比数据的检测算法
对于时间序列(是指将同一统计指标的数值按其发生的时间先后顺序排列而成的数列)来说,T时刻的数值对于T-1时刻有很强的依赖性。比如流量在8:00很多,在8:01时刻的概率是很大的,但是如果07:01时刻对于8:01时刻影响不是很大。
首先,我们可以使用最近时间窗口(T)内的数据遵循某种趋势的现象来做文章。比如我们将T设置为7,则我们取检测值(now_value)和过去7个(记为i)点进行比较,如果大于阈值我们将count加1,如果count超过我们设置的count_num,则认为该点是异常点。
c
o
u
n
t
(
∑
i
=
0
T
(
n
o
w
v
a
l
u
e
−
i
)
>
t
h
r
e
s
h
o
l
d
)
>
c
o
u
n
t
_
n
u
m
count\left( \sum_{i\,\,=0}^T{\left( nowvalue-i \right) >threshold} \right) >count\_num
count(i=0∑T(nowvalue−i)>threshold)>count_num
上面的公式涉及到threshold和count_num两个参数,threshold如何获取我们将在下节进行介绍,而count_num可以根据的需求进行设置,比如对异常敏感,可以设置count_num小一些,而如果对异常不敏感,可以将count_num设置的大一些。
业界关于动态阈值设置的方法有很多,今天介绍一种针对我们lvs流量异常检测的阈值设置方法。通常阈值设置方法会参考过去一段时间内的均值、最大值以及最小值,我们也同样应用此方法。取过去一段时间(比如T窗口)的平均值、最大值以及最小值,然后取max-avg和avg-min的最小值。之所以取最小值的原因是让筛选条件设置的宽松一些,让更多的值通过此条件,减少一些漏报的事件。
t
h
r
e
s
h
o
l
d
=
min
(
max
−
a
v
g
,
a
v
g
−
min
)
threshold\,\,=\,\,\min \left( \max -avg,avg-\min \right)
threshold=min(max−avg,avg−min)
- iForest
iForest算法是周志华老师于2010年设计的一种异常点检测算法,该方法利用数据构建iTree,进而构建iForest,是一种无监督的检测方法,具有很好的效果
这里我们给出该算法的简单介绍:
iForest是由iTree构建而成的,因此我们首先介绍iTree。iTree是一种随机二叉树,每个节点要么有两个子节点,要么该节点为叶子节点。对于给定的数据集D,数据集中的所有的特征都是连续变量,iTree的构造如下:
(1) 在数据集D中随机选择一个特征A;
(2) 随机选择特征A的一个可能取值value;
(3) 根据特征A以及值value将数据集D分为两个子集,将特征A的值小于value的样本归入左子节点,余下部分归入右子节点;
(4)递归构造左右子树直至满足以下的终止条件:
a. 传入的数据集只有一条记录或者多条相同记录
b. 树的高度达到了限定高度
iTree建立好了以后,就可以对数据进行预测了,预测的过程是将测试记录在iTree上面走一遍。iTree能有效的检测异常点是基于异常点都很稀有这一假设,异常点应该在iTree中很快被划分到叶子节点,因此可以利用检测点被分入的叶子节点到根的路径长度h(x)判断检测点x是否为异常点。
在构建好了iTree后就可以构建iForest,iForest中的每棵树在构造时并不是将所有的数据都用上,而是随机采样,抽取一部分构造iTree,尽量保证每棵树都不相同。事实上,如果iTree在构造时运用很多的数据点反而不能得到很好的效果,主要因为数据点会有重叠,因此效果不够显著。而且因为由iTree变成iForest因此S(x,n)的计算公式也要改变,将h(x)变为E(h(x))是检测点x在每棵树上的平均高度。iForest算法在python中有现成的包可以调用。
利用iForest算法进行判断时,如果检测点的孤立森林分数为正数,那么检测点为正常点,否则为异常点
投票机制:
上面介绍了五种检测的方法,每个方法都有每个方法的优缺点,也有每个方法能检测和不能检测的范围。因此单纯依靠一种方法并不能达到我们预期的效果,而且具有很高的误报率。我们借鉴了投票制度中“少数服从多数”的原则,即多数以上符合,我们才认为符合
matlab 缺失值和异常值处理
https://mp.weixin.qq.com/s/LSgcYiyJvhGYc1GbJH8cDw
标准化和归一化
什么时候用归一化?什么时候用标准化?
(1)如果对输出结果范围有要求,用归一化。
(2)如果数据较为稳定,不存在极端的最大最小值,用归一化。
(3)如果数据存在异常值和较多噪音,用标准化,可以间接通过中心化避免异常值和极端值的影响。
1.归一化
最大 - 最小规范化:对原始数据进行线性变换,将数据映射到[0,1]区间
2.标准化
Z-Score标准化:将原始数据映射到均值为0、标准差为1的分布上