当前位置:首页 > 新闻中心 >新闻详情

一文了解时间序列异常检测

发布时间:2020-04-23 23:04:00

 背景介绍
时间序列异常检测是一个经典的问题。

「时间序列」是指某一个指标按照时间的统计或者观测而成的数列。比如,在运维的领域中,某主机每秒的CPU使用率、某业务每分钟的请求数量等,都可以形成一条时间序列;「异常检测」是指对反常的、和历史不同的行为模式识别。如某台一直空闲的机器,CPU使用率突然飙升至100%、某系统在本应业务繁忙的时间段请求数量降为0等等。

由于时间序列可视化成本低、含义明确、规律明显,因此经常被用于运维领域中监控系统的运行状态。由于系统的逐渐庞大,单纯的人力已经不能满足日益增长的监控需求,于是大家开始使用基于规则的异常检测手段,通过机器帮助人判断系统的健康程度。随着场景的继续深入以及相关算法的研究发明,更多的算法被应用于这一领域中,本文将从数据场景、实际场景中面临的挑战、常用的算法三个方面来进行介绍。


数据场景      
「时间序列」是一个很宽泛的集合,不同领域与监控对象的时间序列可能会表现出完全不同的形态,根据监控对象的不同常分为:业务指标、机器指标、网络指标等等。
一般情况下,当我们对业务进行监控时,会按照某种粒度(如每分钟)来统计几个指标,包括:

  • 交易量(请求数):一共有多少请求数量
  • 平均响应时间(平均耗时):所有请求的平均响应时间
  • 响应率(系统成功率):占比多少的请求获得一个响应
  • 成功率(业务成功率):占比多少的请求是业务成功的

     ……
这些指标形态各异,且相同含义的指标在不同行业(如银行某业务的交易量和券商某服务的请求数)的指标特点也不尽相同。
例如,下图即为不同业务的交易量指标,呈现出很强的周期性,而根据实际业务情况的不同,二者形态上会有一些区别。



下图为某系统的响应时间指标,夜间由于交易较少,呈现出较大波动的特性。




运维领域中,我们经常会对机器指标进行监控,来反映机器是否健康运行,下图为不同监控对象的内存指标。



时间序列在各个领域都很常见,下图是物联网领域中某电机的电流大小指标。



实际场景中面临的挑战      

数据形态各异正如上文关于数据场景的介绍,不同指标、甚至不同领域的相同含义的指标,形态也都有较大的差别,难以用一套经验、一种算法来去进行异常检测。
缺少标注由于数据量大、异常情况较多,导致模型训练需要进行大量的数据标注,而真实生产环境中有经验的运维人员日常工作是十分繁重和忙碌的,很难完成统一的系统标注。
实际场景问题实际场景中,会遇到很多现实的问题,如
  • 节假日、活动日的数据表现和平时可能有较大差异
  • 监控目标存在变更或者切换导致指标发生较大的模式改变
  • 数据每天存在一个固定的尖峰(如跑批的压测等),以及发生时间可能有一定的偏差
  • 数据在固定时间存在缺失,或由于数据采集等问题导致数据缺失较长时间
  • 数据有一定的周期特性,但是每个周期的数据绝对值上有一定的差距
效率问题 有些算法训练效率较低、或者检测效率较低,难以适应大规模数据量的检测。



常用算法      
某些情况下,固定阈值可以成为一个比较好的监控方式,如CPU使用率不能长时间超过90%、稳定的系统响应率不能低于99%等等,但是正如上文所述,由于我们实际场景中有各种各样复杂的问题,导致固定阈值的适用范围较小,同时会产生不小比例的误报和漏报。


统计方法
最常用的方法就是基于k-sigma的同比算法,这是一个快速而且有效的算法。简单来说,即当前数据点的状态由之前不同周期的相同位置数据(比如上周或者前一天的同一时刻)决定,通过历史同期的数据分布来确定当前数据的合理波动范围。它的初始假设,是局部数据符合正态分布,所以超出均值±3*标准差的数据是极有可能异常的。

这个算法有效利用了历史同期的数据,避免了全局使用唯一的固定阈值来衡量是否异常,同时还具有算法计算快速、原理易懂可解释的优点。

在实际场景中,很多数据是不符合这种正态分布的假设的,具体使用的标准差倍数仍然是需要设置且很难全局统一的,实际场景中绝不是简单的3倍就可以的。比如某交易量指标在每天业务开始的时候急速上升,导致附近的数据标准差极大;比如数据在每个周期同样的位置有一个尖刺,那么就会显著拉大附近数据的标准差,导致其他位置的数据合理范围变得更宽泛。同时,数据绝不是平稳的、每个周期完全一样的, 很难用单一的统计方式来解决。

预测方法
预测方法是异常检测中最常用的方法,基本思路是通过比较预测值和真实值的差异,判定是否异常。它包括传统的时序预测模型ARIMA、渐进梯度回归树GBRT、长短时记忆网络LSTM以及Facebook开源算法Prophet等等。

篇幅原因,这里我们仅针对每个算法的适用范围和局限进行讨论,不再介绍其原理。
•    ARIMA:适合用于平稳的,较少突增/突降的数据的预测。ARIMA算法使用前一段数据来预测下一个时间点的数据,因此会导致预测有一定的滞后性,易受到异常值的影响;同时需要进行大量的平稳性检验、参数估计等工作。ARIMA共有7个参数,如何选取到合适的参数本身就是一个难题,而考虑季节性因素的升级版SARIMA由于训练开销大,导致自动选取参数极为困难,一般情况下的做法是预设一组参数。

•    GBRT:适用于形态较稳定,有周期特性的数据。为了使GBRT展现更好的算法效果,需要一定的人工经验提取到有效特征。而由于单棵回归树生成的不确定性,导致每次训练后的模型可能产生较大差别,检测结果不稳定同时可解释性也较弱。
•    LSTM:适用于高频、形态不限的数据。LSTM同样是使用前一段数据来预测下一个时间点的数据,也有着类似的局限。另外,我们日常所见的数据时序属性较弱,统计属性更强(比如1,2后面跟着的不一定是3,更可能是1,因为上周期同位置是1),不太适合LSTM来发挥效果。

•    Prophet:适用于形态较稳定,有周期特性的数据,同时考虑了节假日的特性。由于Prophet采用傅里叶级数来处理周期性因子,导致一般夜间(波动较小)的数据情况较难预测准确;它更关注整体的波动状态,对一些局部信息的捕捉较差。

姑且不谈实际场景下要实现准确预测确实是一件很难的事情(上述算法并没有某个单一算法能够适应我们日常中所接触到的各类数据),所有基于预测的方法都面临一个问题:“偏离预测值多少才算异常?”我们一般会采用训练集误差的某个百分位数或误差的均值+k倍的标准差等方法,其实很难做到特别准确。而在面对每个时间段数据绝对数值不同的情况时,更是如此。

有监督学习方法
有监督的算法有很多,如基于树模型的随机森林、lightGBM,神经网络MLP等等,其整体思路是提取各种各样的统计特征(如前几个数据点的原始值,最近一段时间的均值、标准差、偏度等等),直接丢给模型去训练,算法会根据标注自动选择最有效的特征用以建模。有监督算法往往可以获得更高的算法准确度,但缺点也是十分明显的——最大的问题就是,我们需要大量的人工标注,覆盖全面的数据类型和异常情况,而这在实际场景中是极难实现的。实际生产中,我们极少考虑这类算法,除非异常场景很明确且历史中存在多次相似的情况。

深度学习生成模型
最近几年,通过深度学习生成模型来做异常检测的算法越来越多,效果甚至可以超过一般的有监督学习方法,常见模型有生成对抗网络GAN、变分自编码器VAE等。VAE的原理可以简单理解为:将高维数据压缩至某一个特定维度大小,采样后将其还原至与原始数据同样的维度。其学习的目标是尽可能缩小还原的数据与原始数据之间的差距。基于“数据正常的模式高频出现,而异常极少出现”的想法,「压缩-还原」的过程会找到主要数据模式,而不会将异常模式进行还原。这样,通过还原数据和真实数据的差值大小,可以推测数据的异常程度。

生成模型的优势就是算法准确率高、极少人工干预,但单纯的算法仍存在一些不足。如需要长时间表现稳定的历史数据,需要较长的训练时间,且同样会面临衡量差值大小与异常的关系这类问题等等。

必示业务指标异常检测
根据实际场景中遇到的各种挑战,以及参考各个算法擅长的场景类型,必示异常检测的整体架构设计如下图所示:

我们知道,kpi的形态各异,而每种数据形态所适应的检测算法或应提取的特征都是不尽相同的。所以对于一条时间序列,首先在「特征描述器」部分对其特征进行表述。关注的特征包括:

•    时间序列的周期特性
•    时间序列的趋势特性
•    时间序列的抖动程度
    ……

根据时间序列的特征,计算资源的分配以及历史数据长度,在「检测器」部分自动匹配不同模型组合与不同特征生成,进行针对性训练并生成全新模型。在这一过程中,不同模型提供的算法包括:

•    变分自编码器
•    渐进梯度回归树
•    极值理论
•    周期性尖峰消失检测
    ……

在「分类器」中对不同模型的结果进行组合,得到最终的预测合理范围(基带),在此基础之上进行实时的异常检测,并同时支持横向拓展检测数据。


总结      
必示业务指标异常检测是基于真实的业务场景而生。除了使用目前业界表现突出的异常检测算法组合,还针对各种日常运维中遇到的特殊情况做了大量算法层面的优化(如跑批行为、变更行为、特殊日),可以更好地适应实际需求,减少由此带来的误报和漏报。通过对历史数据的学习,自动分析合理的动态阈值,减少人工配置「一刀切」导致的难以平衡阈值准确性与包容性的问题。







 

TOP

010-82362970