# 技术黑板报 # 第十期
推荐阅读时长:15min
在上一篇技术黑板报中,我们介绍了频繁项集挖掘这一问题,并讲解了Apriori算法与FP-Growth算法的技术原理。本期技术黑板报我们将主要围绕频繁项集挖掘算法的实际应用,即当该算法应用到告警关联场景中时,我们遇到了哪些问题,如何解决这些问题,以及我们如何在原始FP-Growth算法的基础上进行改进,从而研发了专用于告警关联场景下的CW-FP-Growth算法。为了展示该算法的实际效果,我们在文末给出了这一算法在脱敏数据中的案例。
章节目录
一、频繁项集挖掘与告警关联如何结合?
二、ACorFrepm算法的实际效果
三、总结
一、频繁项集挖掘与告警关联如何结合?
在前文中,我们介绍了频繁项集挖掘问题以及两种典型的算法,然而如何将频繁项集挖掘算法应用到告警关联及降噪中?为了回答这一问题,我们可以先简要分析一些运维的典型场景。在实际运维过程中经常会出现如下情况,系统短时间内产生了大量的告警,其中部分告警的内容具备较高的重复性,或这些告警之间彼此存在一定的关联关系,如果每条告警都通知,那么用户可能会收到大量的信息,然而并非每一条信息都具备很高的分析价值,这些重复或无意义的通知并不能帮助运维人员加速定位故障,反而很大程度上耗费了他们的精力,令他们不能专注于那些真正需要解决的故障。那么如何解决这一问题?
产生这一问题的主要原因在于告警之间缺乏分析,如果能够在通知运维人员之前,对告警进行一些初步的关联分析与降噪,则能给减少运维人员接受到的重复通知,因此我们尝试了从时间相关性的角度找出需要分析的目标告警的相关告警,这些相关告警与目标告警可能属于同一根因,或能够为查找目标告警的根因提供更多的信息,从而帮助运维人员分析故障之间的关联关系,使运维人员能够加速根因定位的过程。基于这一目标,我们采用频繁项集挖掘算法从故障的发生时间入手,挖掘故障之间的关联规则,从而将这些关联规则中可信程度比较高的部分用于告警降噪中。而在应用这一算法的过程中,我们也经常被问到一些算法逻辑的相关问题,在这里我们将简单的介绍这些问题的解决方法。
问题一:如何在数据中挖掘尽可能多的关联规则?
在商品推荐的场景中,原始的数据库由多个项集组成,每个项集是消费者购买商品的记录,也就是说这些记录彼此之间的界限十分明确,而在告警关联的场景中,告警是连续不断生成的,因此如何将这些告警分割为项集成为了我们在挖掘关联规则中面临的第一个问题。
我们实验的第一种方法是采用滑动的时间窗口解决这一问题,将固定时间的窗口按照1分钟的步长进行滑动,则上午10:00-10:05内的告警被划分为第一个集合,10:01-10:06内的告警被划分为第二个集合,以此类推。这虽然实现了跨窗口挖掘规则,但这一设想引发了新的问题,假设存在规则出现在10:04-10:05这段时间内,那么即使这一规则只出现了一次,但却出现在了4个不同的告警项集中,这将使得频繁项集算法挖掘算法产生大量的错误判断。
为了避免这种数据重复出现带来的影响,我们决定采用一种变通的方法,即采用了多个固定窗口组合的方式解决这种问题,通过将多个不同起始时间和切分时间的窗口的结果加以组合,以挖掘出同一份数据所有可能的关联规则,接着采用邻接矩阵记录多个项之间的关联度用于筛选并合并多次挖掘产生的重复或冲突的规则。
问题二:如何设计才能更方便用户理解并调整算法的相关参数?
在对频繁项集挖掘这一问题的介绍中,我们引出了支持度这一概念,然而传统的支持度计算方法并不适用于告警关联场景中,或者说不符合用户的调参直觉。同样一批数据在不同的时间窗口下产生的告警项集个数并不相同,这导致用户很难根据内心的期望准确的评估支持度阈值的大小,导致体验变差。
针对这一问题,我们采用了告警出现在几个项集中作为当前项的支持度,比如对于项集[A, B, C],[B, C, D],[D, F, A],由于告警类别B出现在了项集[A, B, C]和[B, C, D]中,因此支持度为2。这近似于将某类告警中的告警个数作为此类告警的支持度,这种方式相比于传统的计算支持度的方法更加符合用户的主观感知,便于用户按照自己的期望使用算法。
问题三:如何处理项集中的重复项,处理方法是否合理?
在多个不同的用户场景中,我们经常被问到这个问题,为解决重复项的问题,我们最终选择了保留其中之一的方式。因为项集[A,B,C]和项集[A,A,B,C]在计算项A的支持度时的贡献度是一致的,都会使项A的支持度加1。而如果不去重,则重复项将会干扰FP树的构建过程,比如对于项集[A, B, C]和项集[A, A, B, C],这两个不同的项集将构建出一个长度为3的分支和一个长度为4的分支,但他们仅具备一个公共节点A,图示如下,这导致FP树产生了不必要的分支,并可能会挖掘出类似于[A,A]这种无用的关联规则。而保留其中之一的方法能够在不影响结果的前提下解决这一问题,虽然简单但是具备合理性。
问题四:如何选择聚类维度?
在完成数据的预处理后,我们仍然面临一个重要问题,即该以什么维度聚合告警?在介绍频繁项集挖掘的基本概念时,我们可以发现啤酒不管是哪种牌子,什么规格,他们都属于啤酒,不可能出现一瓶啤酒被误认为是鸡蛋的情况,也就是说,商品本身具有类别属性,而在告警关联场景中,告警又该如何被划分类别呢?
一种常见的方法是采用IP进行划分,将告警按照IP聚类后,采用该算法确实可以找出系统中经常同时出现故障的IP。但这一方法也存在两个问题,首先不是所有告警都具备IP信息,这使得此类方法的使用存在一定的限制条件,其次这些主机并不一定每次都出现同样的故障,这使得该方法得到的关联规则并不准确。以上的两个问题使得采用IP作为聚类维度虽然可行但并不总能得到好的结果,是否存在更适合的维度呢?
经过实验验证,我们更希望从故障的维度聚类告警,即将描述同一故障的告警聚合为一类,并通过频繁项集挖掘类算法找出哪些经常一起出现的故障。根据我们的定义,警报与故障应当具备一一对应关系,因此实际使用过程中,我们更加推荐用户选择警报ID作为告警聚合的维度。
问题五:如何选择生成关联规则的评价指标?
经过实际调研,我们发现用户更加关心的是哪些规则经常出现,哪些规则在应用到告警降噪过程时不会产生错误压缩的情况,也就是说用户更加关注规则的支持度与置信度,而对于规则之间的关联关系的强度则需要运维人员亲自判断,并非单纯的通过计算获得。
在实验过程中我们发现提升度很难被直接应用在实际场景下,提升度的计算很容易受支持度计算方式的影响,通俗来说,如果按照原始的支持度计算方法,当项集数较大时,X和Y的支持度都将出现明显的下降,这将极大的影响提升度这一指标的实际计算结果,因此实际场景中提升度的结果并不像预想中那么准确。
综上所述,最终可以选择置信度和支持度作为关联规则的评价指标,并在计算某个关联规则的置信程度时,计算这一规则对所有子规则的可信程度,并选则最低值作为当前规则的最终置信度。
二、ACorFrepm算法的实际效果
基于上述在将频繁项集挖掘算法应用于告警关联这一场景中的各种问题,我们在原始FP-Growth算法的基础上进行改进,从而研发了专用于告警关联场景下的ACorFrepm算法,为了验证这一算法能否满足实际运维场景的性能和效果要求,我们做了如下实验。
1、算法性能
为了测试算法的性能,我们利用大批量的模拟数据测试了算法的计算时长,其中项的个数用于模拟实际使用过程中的警报个数,单个项集最大长度用于模拟警报的最多出现次数,时间控制在1小时内,时间窗口选为5分钟,则共计12个项。
# 时间性能:
通过上述实验结果,我们可以看出,真正影响这一算法计算效率的是划分后项集的平均长度以及频繁项的个数,数据总量的影响并不显著。由于实际数据中频繁项数目较少,因此经过多次实际场景检验,对于一小时内的上万条告警数据的计算平均时间不超过10秒,但这一数值根据实际数据中频繁项的个数出现波动。
# 空间性能:
上述实验表明算法能够在短时间内挖掘出一百万关联规则,远超实际数据中可能出现的关联规则数,空间占用较小,即空间性能几乎能够满足任何实际数据的需求。
2、算法效果
为了验证算法的实际效果,我们在电网,运营商,银行等多个实际业务场景中检验了该算法,其中的部分关联规则案例如下。
在某网的实际业务脱敏数据中,我们找出了由成员端口状态down产生的告警与聚合接口告警之间的关联规则。从文本描述中可以明显的看出,当接口发出告警时,对应的聚合接口也会在同一时刻发出告警,这些告警具备较强的时间共现特性,同时文本具有明显的关联,建议合并分析。
在某农商行的实际业务脱敏数据中,我们找出了当队列阻塞并触发自愈脚本产生的告警与系统恢复正常给出的告警之间的关联规则。当程序阻塞并间隔一段时间后恢复正常,从文本内容中可以看出两条描述具备高度关联性,从时间上也均为10分钟以内固定一起出现的警报,因此可以合并分析。
五、总结
在本篇文章中,我们介绍了频繁项集挖掘这一问题,并讲解了基础算法Apriori和目前较为先进的算法FP-Growth,并详细描述这类问题的相关概念及实现步骤,同时讲解了如何将这一算法应用到告警关联场景中,进而实现告警降噪的功能。并介绍了我们对FP-Growth算法作出的改进,以使它能够更好的应用到告警关联场景中,文末我们给出了改进后算法的实际效果案例和性能说明,感谢您的阅读。
END