异常检测系列(一)

基于特征取值属性共现的异常检测模型(CBRW)

背景

最近在做异常检测方面的研究,读到了一些论文,略有收获,因此以专栏文章的形式记录下来,也可作为资料方便自己日后查阅

一. 异常

异常的定义

根据具体的场景会有不同。如流量异常检测场景下,流量突然暴涨被定义为异常;账号行为异常检测场景下,如果账号注册之后从无活动,或者突然大量的活动序列可被定义为异常;在产品质量异常检测方面,误差在3 (-3\delta,3\delta) 范围之外的产品可被定义为异常;又比如浙江乐清滴滴顺风车司机,也是顺风车司机群体中的异常……总的来说,不希望出现的、对系统有害的,就是异常。

2. 异常检测的困难

在很多场景下,异常检测困难,是因为其并不会经常出现,数据样本很少(批量注册账号、恶意攻击这种另论),导致复现困难、观察不易。

二. 常用的异常检测方法

有监督学习

异常检测问题,也可以定义为分类问题。现有的方法如GBDT、LR、XGboost等方法分类方法都可以用来做异常检测。但是异常数据一般是非常偏斜的,正常异常比可能是100:1甚至是1000:1。如果异常分很多类的话,那么每种异常的占比更少。同时,还需要不断地累积标签。算法调参也是一个很麻烦的问题,一般来说计算量很大。在数据偏斜的情形下,算法效果也成问题。

2. 无监督学习

无监督学习方法则不需要累积标签,通常也不会有大量的参数。常用的算法如:FPGrowth[1]、Apriori、PrefixSpan[2]、Isolation Forest[3]、LOF[4]算法,以及本文的CBRW[5]算法。FPGrowth算法、PrefixSpan算法只有两个参数,即最小支持度和最小置信度;Isolation Forest算法只需要设置树的个数等。

三. CBRW算法

CBRW算法的优点:

  1)对每个特征的取值,都计算了一个异常度分数

  2)异常度分数可以用来进行异常检测的特征选择,或者直接进行异常检测

2. CBRW算法的具体内容

CBRW算法主要针对类别变量数据,故而用户的所有特征数据都应是离散的,若是连续变量也需进行离散化转化为离散型变量。对于数据集合 X=\{x_1,x_2,x_3,……,x_N\} ,共有D个特征,特征集合为 F=\{f_1,f_2,……,f_D\} 共D个特征,每个特征下有不同数量的类别取值。

1) 有向加权图 G=(V,E)

其中 V 是由属性取值构成,边的权重由条件概率组成,后面将详述

2) 一些定义

特征mode:

一个特征的mode定义为该特征取值出现最多的那个取值,即: mode(f_i)=max\{p(v_1),p(v_2)……\},v_j\in f_i ,记为 p(m) ,其中 p(v_i)=\frac{frequency(v_i)}{N}

特征内异常度:

\delta(v)=\frac{1}{2}(dev(v)+base(m))

dev(v)=\frac{p(m)-p(v)}{p(m)} base(m)=1-p(m)

其中 v 属于同一特征 f

边权重:

节点 u\rightarrow v 的权重 A(u,v)=\frac{p(u,v)}{p(v)}  其中 p(u,v) 是属性 u 和 v 的共现概率, p(v) 是属性 v的出现概率,若 u=v 则 p(u,v)=0

可以这样理解:若 u 很异常,且 (u,v) 有很强的关联性,那么 v 必然也很异常,即异常性由 u 传递到了 v ,其中 p(u|v) 在频繁模式挖掘中,代表置信度,这里可以从 u 反推 v

随机游走:

令 \pi_t\in R^{|V|} 为时间 t 的随机漫步的概率分布,于是有:\pi_{t+1}=W_{b}^{T}\pi_t

即\pi_{t+1}(v)=\sum_{v\in V}{W_b(u,v)}\pi_t(u)

根据定理:若 图G 是不可还原的且非周期的,则 \pi 将收敛到一个静态的概率分布

\pi^{*} s.t. \pi^{*}=W_{b}^{T} \pi^{*}

根据上式可以得出: 最终的静态概率分布\pi^{*} 与其初始化无关

伪代码:

异常检测系列(一)_第1张图片

随机游走算法

其中 \pi_{t+1}=(1-\alpha)\frac{1}{|V|}+\alpha W_{b}^{T} \pi_{t} 中的 \alpha 是为了保证该式子收敛, \alpha \in [0.85,0.95]

四. 异常度

通过上述算法迭代之后得到的 \pi ,即为异常度向量

1) 特征取值的异常度:

迭代得到 \pi 之后,可得到每个特征取值的异常度

value\_score(v)=\pi(v) 

s.t. v\in V  0<\pi(v)<1 \sum_{v \in V}{\pi(v)}=1

2) 特征的异常相关性rel(f):

rel(f)=\sum_{v\in f}value\_score(v)

rel(f) 的大小代表了该特征与异常的相关性,该值越大,则表示该特征与异常越相关,可用于异常检测时的特征选择

3)样本的异常度分数 object\_score(x) :

object\_score(x) = \sum_{f\in F}{w_f} \times value\_score(g_f(x))

其中 w_f=\frac{rel(f)}{\sum_{f \in F}{rel(f)}}

通过以上方式,可以计算得到每个特征取值,每个特征,每个数据的异常度

五. 算法复杂度

上述算法最耗时的在于计算共现概率,如果有 V个特征取值,那么就需要算 V^2 个属性共现对的频率,这是最耗时的,至于其他计算都是简单的加减运算

六. 算法实现

算法已经利用Spark实现,后续将会在Github上开放供参考,计算效果也会在后续利用测试数据进行展示

谢谢阅读!

参考文献:

[1]Pei J, Han J, Lakshmanan L V S. Mining Frequent Item Sets with Convertible Constraints[C]// International Conference on Data Engineering, 2001. Proceedings. IEEE, 2002:433-442.

[2]Pei J, Han J, Mortazaviasl B, et al. PrefixSpan: Mining Sequential Patterns Efficiently by Prefix-Projected Pattern Growth[C]// International Conference on Data Engineering. IEEE Computer Society, 2001:215.

[3]Liu F T, Kai M T, Zhou Z H. Isolation Forest[C]// Eighth IEEE International Conference on Data Mining. IEEE, 2009:413-422.

[4] Pang G, Cao L, Chen L. Outlier Detection in Complex Categorical Data by Modeling the Feature Value Couplings[C]// International Joint Conference on Artificial Intelligence. 2016.

你可能感兴趣的:(异常检测系列(一))