AIOps探索:基于VAE模型的周期性KPI异常检测方法

AIOps探索:基于VAE模型的周期性KPI异常检测方法

作者:林锦进

前言

在智能运维领域中,由于缺少异常样本,有监督方法的使用场景受限。因此,如何利用无监督方法对海量KPI进行异常检测是我们在智能运维领域探索的方向之一。最近学习了清华裴丹团队发表在WWW 2018会议上提出利用VAE模型进行周期性KPI无监督异常检测的论文:《Unsupervised Anomaly Detection via Variational Auto-Encoder for Seasonal KPIs in Web Applications 》[1](以下简称为Dount)。基于Dount论文的学习,本文将介绍如何使用Keras库,实现基于VAE模型的周期性KPI异常检测方法,包括其思路、原理与代码实现,帮助大家理解这个方法。

背景介绍:

在AI in All的时代,工业界中的运维领域提出了:智能运维(AIOps, Artificial Intelligence for IT Operations)这个概念,即采用机器学习、数据挖掘或深度学习等方法,来解决KPI异常检测、故障根因分析、容量预测等运维领域中的关键问题。

其中KPI异常检测是在运维领域中非常重要的一个环节。KPI(key performance indicators)指的是对服务、系统等运维对象的监控指标(如延迟、吞吐量等)。其存储的形式是按其发生的时间先后顺序排列而成的数列,也就是我们通常所说的时间序列。从运维的角度来看,存在多种不同类型的KPI,周期性KPI是其中一种典型的KPI,其特点表现为具有周期性,如下图:

要进行KPI异常检测,首先我们要定义一下什么是异常。如上图所示,我们将KPI的异常点定义为超过期望值一定范围的点,而在期望值的小范围内波动的点我们将其认为是噪声。对周期性KPI的异常检测在工业界和学术界已有不少探索,本文将介绍基于深度学习模型VAE的无监督周期性KPI异常检测方法。

正文:

AutoEncoder

因为VAE跟AutoEncoder在网络整体结构上相似,都分为Encoder和Decoder模型,那么在了解VAE之前,我们先了解什么是AutoEncoder模型。

AutoEncoder的意思是自编码器,这个模型主要由两个部分组成:encoder和decoder,可以把它理解为两个函数:z = encoder(x), x = decoder(z)。在AutoEncoder模型的思想中,我们期望能够利用encoder模型,将我们的输入X转换到一个对应的z,利用decoder模型,我们能够将z还原为原来的x,可以把AutoEncoder理解为有损的压缩与解压。

AutoEncoder模型有什么用呢?有两个主要功能:

降噪

将高纬的特征转为低纬度的特征(从X到z)。

要实现一个AutoEncoder其实非常简单(其实就是单个隐藏层的神经网络),有接触过深度学习的人应该都可以理解:

input=Input(shape=(seq_len,))encoded=Dense(encoding_dim,activation='relu')(input)decoded=Dense(seq_len)(encoded)autoencoder=Model(input,decoded)

我们先来考虑一下能否用AutoEncoder进行KPI异常检测,以及它有什么缺点。因为AutoEncoder具有降噪的功能,那它理论上也有过滤异常点的能力,因此我们可以考虑是否可以用AutoEncoder对原始输入进行重构,将重构后的结果与原始输入进行对比,在某些点上相差特别大的话,我们可以认为原始输入在这个时间点上是一个异常点。

下面是一个简单的实验结果展示,我们训练了一个输入层X的维度设置为180(1分钟1个点,3小时数据),Z的维度设置为5(可以理解为原始输入降维后表达),输出成X的维度设置为180的AutoEncoder模型,并且测试集的数据进行重构(滑动窗口形式,每次重构后只记录最后一个点,然后窗口滑动到下一个时间点),能够得到以下结果:

基于AutoEncoder的周期性KPI异常检测:

上面提到,AutoEncoder具有降噪功能,那它怎么降噪呢?这里简单举一个例子:假设我们现在训练出来的模型可以得到这样的映射关系[1, 2](X)->[1](z)->[1 ,2]X_r, 其中[1, 2]表示二维向量, [1]表示一维向量,X_r表示重构后的X。这个例子表示了一个理想的AutoEncoder模型,它能将[1,2]降维到[1], 并且能从[1]重构为[1,2]。接下来,假设我们的输入为[1, 2.1],其中第二维度的0.1表示一个噪声,将其输入到encoder部分后得到的Z为[1],并且重构后得到的X_r是[1, 2], 这也就达到了一个对原始输入去噪的作用。

而我们的当前的目标是进行KPI异常检测,从上图可以看到,一些肉眼可见的异常在重构后被去除掉了(类似降噪了),通过对比与原始输入的差距,我们可以判断是否为异常。

然而,AutoEncoder模型本身没有什么多少正则化手段,容易过拟合,当训练数据存在较多异常点的时候,可能模型的效果就不会特别好,而我们要做的是无监督异常检测(要是有label的话就用有监督模型了),因此我们的场景是训练的时候允许数据存在少量异常值的,但当异常值占比较大的话,AutoEncoder可能会过拟合(学习到异常模式)。

Variational AutoEncoder(VAE)

接下来介绍一些VAE模型,如果不需要对VAE有比较清楚的了解,也可以直接跳过这部分内容。

对于VAE模型的基本思想,下面内容主要引用自我觉得讲得比较清楚的一篇知乎文章,并根据我的理解将文中一些地方进行修改,保留核心部分,这里假设读者知道判别模型与生成模型的相关概念。

原文地址:https://zhuanlan.zhihu.com/p/27865705

VAE 跟传统 AutoEncoder关系并不大,只是思想及架构上也有 Encoder 和 Decoder 两个结构而已。VAE 理论涉及到的主要背景知识包括:隐变量(Latent Variable Models)、变分推理(Variational Inference)、Reparameterization Trick 等等。





 。




下图展示了一个具有3个隐变量的 VAE 结构示意图。

基于VAE的周期性KPI异常检测

上面介绍了VAE的原理,看起来很复杂,其实最终VAE也实现了跟AutoEncoder类似的作用,输入一个序列,得到一个隐变量(从隐变量的分布中采样得到),然后将隐变量重构成原始输入。不同的是,VAE学习到的是隐变量的分布(允许隐变量存在一定的噪声和随机性),因此可以具有类似正则化防止过拟合的作用。

以下的构建一个VAE模型的keras代码,修改自keras的example代码,具体参数参考了Dount论文:

def sampling(args):

    """Reparameterization

trick by sampling fr an isotropic unit Gaussian.

    # Arguments:

        args (tensor): mean and logof variance of Q(z|X)

    # Returns:

        z (tensor): sampled latentvector

    """

    z_mean, z_log_var=args

    batch=K.shape(z_mean)[0]

    dim=K.int_shape(z_mean)[1]

    # by default,

random_normal has mean=0 and std=1.0

    epsilon=K.random_normal(shape=(batch,dim))

    std_epsilon=1e-4

    returnz_mean+(z_log_var+std_epsilon)*epsilon


input_shape=(seq_len,)

intermediate_dim=100

latent_dim=latent_dim


# VAE model = encoder + decoder

# build encoder model

inputs=Input(shape=input_shape, name='encoder_input')

x=Dense(intermediate_dim, activation='relu', kernel_regularizer=regularizers.l2(0.001))(inputs)

x=Dense(intermediate_dim, activation='relu', kernel_regularizer=regularizers.l2(0.001))(x)

z_mean=Dense(latent_dim, name='z_mean')(x)

z_log_var=Dense(latent_dim, name='z_log_var', activation='softplus')(x)


# use reparameterization trick to push the sampling out

as input

# note that "output_shape" isn't necessary with

the TensorFlow backend

z=Lambda(sampling, output_shape=(latent_dim,), name='z')([z_mean, z_log_var])


# build decoder model

x=Dense(intermediate_dim, activation='relu', kernel_regularizer=regularizers.l2(0.001))(z)

x=Dense(intermediate_dim, activation='relu', kernel_regularizer=regularizers.l2(0.001))(x)

x_mean=Dense(seq_len, name='x_mean')(x)

x_log_var=Dense(seq_len, name='x_log_var', activation='softplus')(x)

outputs=Lambda(sampling, output_shape=(seq_len,), name='x')([x_mean, x_log_var])


vae=Model(inputs, outputs, name='vae_mlp')


# add loss

reconstruction_loss=mean_squared_error(inputs, outputs)

reconstruction_loss*=seq_len

kl_loss=1+z_log_var-K.square(z_mean)-K.exp(z_log_var)

kl_loss=K.sum(kl_loss, axis=-1)

kl_loss*=-0.5

vae_loss=K.mean(reconstruction_loss+kl_loss)

vae.add_loss(vae_loss)


vae.compile(optimizer='adam')


基于VAE的周期性KPI异常检测方法其实跟AutoEncoder基本一致,可以使用重构误差来判断异常,来下面是结果,上图是原始输入,下图是重构结果,我们能够看到VAE重构的结果比AutoEncoder的更好一些。

缺陷:

基于AutoEncoder和VAE模型在工业界上的使用面临的2个最大问题是:

理论上它只能对一个KPI训练单独一个模型,不同类型的KPI需要使用不同的模型,为了解决这个问题,裴丹团队后面又发表了一篇关于KPI聚类的论文《Robust and Rapid Clustering of KPIs for Large-Scale Anomaly Detection》,先对不同的KPI进行模板提取,然后进行聚类,对每个类训练单独一个模型。

需要设置异常阈值。因为我们检测异常是通过对比重构后的结果与原始输入的差距,而这个差距多少就算是异常需要人为定义,然而对于大量的不同类型的KPI,我们很难去统一设置阈值,这也是采用VAE模型比较大的一个缺陷。虽然在Dount论文中,采用的是重构概率而不是重构误差来判断异常,然而重构概率也需要设置阈值才能得到比较精确的结果。

总结

本文分别介绍了AutoEncoder和VAE模型以及基于这些模型的周期性KPI异常检测方法。裴丹的论文Dount中对原始的VAE做了一些改进,针对KPI异常检测这个场景增加了一些细节上的优化,如missing data injection、MCMC等等,这部分细节就不在本文中讨论了,有兴趣的同学可以看一下他们的开源代码 haowen-xu/donut

最后,为了让对AIOps有兴趣的同学能够交流与学习,我创建了一个Awesome-AIOps的仓库,汇总一些AIOps相关的学习资料、算法/工具库等等,欢迎大家进行一起补充,互相进步。

linjinjin123/awesome-AIOps​github.com

如果文中有什么解释不清或者说错的地方,欢迎批评指正。

参考文献

[1] Unsupervised Anomaly Detection via Variational Auto-Encoder for Seasonal KPIs in Web Applications

[2] https://blog.keras.io/building-autoencoders-in-keras.html

[3] 当我们在谈论 Deep Learning:AutoEncoder 及其相关模型


来源:https://zhuanlan.zhihu.com/p/45400663

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容