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

转载自 https://mp.weixin.qq.com/s/g6xwiRYhNyulwLlBYLh-4Q?scene=25
仅仅用于学习方面,如有侵权,请联系 root@smileyan.cn

背景介绍

「时间序列」是指某一个指标按照时间的统计或者观测而成的数列。比如,在运维的领域中,某主机每秒的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的形态各异,而每种数据形态所适应的检测算法或应提取的特征都是不尽相同的。所以对于一条时间序列,首先在「特征描述器」部分对其特征进行表述。关注的特征包括:

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

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

  • 变分自编码器

  • 渐进梯度回归树

  • 极值理论

  • 周期性尖峰消失检测

  • ……

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

总结

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

转载自 https://mp.weixin.qq.com/s/g6xwiRYhNyulwLlBYLh-4Q?scene=25
仅仅用于学习方面,如有侵权,请联系 root@smileyan.cn

### 关于八种异常检测算法的详细解释 #### 1. 监督异常检测 (Supervised Anomaly Detection) 监督异常检测依赖于已标注的数据集来区分正常和异常情况。通过这些标签,可以构建分类模型以预测新数据点的状态。常用的算法有逻辑回归、支持向量机和支持向量机变体如C-SVM、ν-SVM等,还有决策树及其集成版本随机森林。 ```python from sklearn.svm import SVC clf = SVC() clf.fit(X_train, y_train) predictions = clf.predict(X_test) ``` 这种类型的检测适用于拥有充足标记样本的情况[^2]。 #### 2. 无监督异常检测 (Unsupervised Anomaly Detection) 当缺乏足够的带标签数据时,则可采用无监督的方法来进行异常探测。这类方法利用了数据内在结构特性而不需额外的信息指导。典型代表包括k-means聚类、DBSCAN密度基空间聚类以及孤立森林(Isolation Forests),后者特别适合处理高维稀疏数据。 ```python from sklearn.ensemble import IsolationForest iso_forest = IsolationForest(contamination=0.1) y_pred = iso_forest.fit_predict(X) ``` 此方式能够有效应对未知类别或难以获取标签的情形。 #### 3. 半监督异常检测 (Semi-Supervised Anomaly Detection) 介于两者之间的是半监督模式,在这里仅有部分实例被赋予真值指示其状态;其余大部分保持未定。此类场景下常见的策略涉及自编码器(autoencoders)与生成对抗网络(GANs)相结合的形式——即所谓的“深度置信网”。 ```python import tensorflow as tf autoencoder = tf.keras.models.Sequential([ ... ]) history = autoencoder.fit(x_train_noisy, x_train, epochs=epochs, batch_size=batch_size, shuffle=True, validation_data=(x_val_noisy, x_val)) ``` 这种方法充分利用有限数量的手动标注资源提升整体效果。 #### 4. 在线异常检测 (Online Anomaly Detection) 在线环境下的挑战在于必须即时响应不断流入的新观测值,并及时调整内部参数适应变化趋势。为此设计了一系列增量更新机制,比如Hoeffding Trees(霍夫丁树)、Adaptive Resonance Theory Networks(ART神经网络),它们能够在不影响现有知识的前提下逐步纳入最新信息源。 ```python from skmultiflow.trees.hoeffding_tree import HoeffdingTreeClassifier ht = HoeffdingTreeClassifier() for i in range(n_samples): ht.partial_fit([X[i]], [y[i]]) ``` 该方案非常适合动态背景下连续监控任务的需求。 #### 5. 基于距离/相似度测量的距离型异常检测(Distance-based Anomaly Detection) 基于欧几里得或其他形式的距离测度计算个体间差异程度作为判断依据之一。LOF局部离群因子(Local Outlier Factor)便是其中一员,它衡量目标对象相对于周围邻居位置偏离平均状况的程度。 ```python from pyod.models.lof import LOF detector = LOF() detector.fit(X) scores_pred = detector.decision_function(X_test) ``` 这种方式直观易懂且易于实现,但在维度灾难面前可能遭遇瓶颈[^1]。 #### 6. 统计学基础的概率型异常检测(Statistical-based Anomaly Detection) 运用经典统计理论框架内建立假设检验流程,例如格鲁布斯准则(Grubbs' test)用于单变量集合中寻找极端偏差成员。对于多元情形则存在马氏距离(Mahalanobis Distance)这样的工具可供选用。 ```python from scipy.stats import chi2 def mahalanobis(x=None, data=None, cov=None): """Compute the Mahalanobis distance.""" x_minus_mu = x - np.mean(data) inv_covmat = sp.linalg.inv(np.cov(data.T)) left_term = np.dot(x_minus_mu, inv_covmat) mahal_dist = np.dot(left_term, x_minus_mu.T) return math.sqrt(mahal_dist) ``` 上述过程严格遵循数理推导路径确保结论可靠性。 #### 7. 时间序列特定的时间序列异常检测(Time Series-specific Anomaly Detection) 考虑到顺序排列特点而专门定制化的解决方案,像ARIMA差分整合移动平均自回归模型(Autoregressive Integrated Moving Average Model)就专攻于此领域。近年来兴起的一些研究还探索了如何借助LSTM长短记忆单元(Long Short-Term Memory Units)捕捉长期依赖关系从而改善预报精度。 ```python model = Sequential() model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1],1))) model.compile(optimizer='adam', loss='mean_squared_error') model.fit(X_train, y_train, epochs=1, batch_size=1, verbose=2) ``` 这有助于更精准地把握随时间演变规律并提前预警潜在风险事件的发生可能性[^4]。 #### 8. 对抗性训练增强的异常检测(Adversarial Training-enhanced Anomaly Detection) 引入GAN架构理念创造一对相互对立又彼此促进的学习实体:一个是负责生成看似真实的伪造品的生成器(generator),另一个则是试图分辨真假混杂输入流判别器(discriminator). USAD就是这样一种创新性的尝试,旨在克服传统单一视角局限性的同时提高泛化能力。 ```python class Generator(tf.keras.Model): def __init__(self): super().__init__() ... class Discriminator(tf.keras.Model): def __init__(self): super().__init__() ... generator_optimizer = tf.keras.optimizers.Adam(1e-4) discriminator_optimizer = tf.keras.optimizers.Adam(1e-4) checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt") checkpoint = tf.train.Checkpoint(generator_optimizer=generator_optimizer, discriminator_optimizer=discriminator_optimizer, generator=generator, discriminator=discriminator) ``` 如此这般既强化了系统的稳健性和灵活性,也为后续改进留下了广阔的空间。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值