算法假设
iForest(孤立森林)是一个无监督、高性能的异常挖掘算法,它利用异常点的两个基本特性:1)它们是数据集中的少数 2)它们的某些属性取值很不同于正常数据。
Isolation
作者首先给出孤立(isolation)的定义,它指的是将一个实例从其它实例中分离出去,由于异常点在数据中是少量且异常的,因此它们对于isolation操作更加的“敏感”。
The term isolation **means ‘separating an instance from the rest of the instances’. Since anomalies are ‘few and different’ and therefore they are more susceptible to isolation.
具体来说,如果我们想通过随机切分(从数据的任意一个维度取最大值与最小值之间的一个随机值进行切分)的方式将一个点从群体中孤立出来。正常点相比于异常点要更难,体现在正常点需要多次操作才能完全孤立出来,而异常点少量操作就可以了。
为了证实上面的想法,作者给出了一个具体的实例。通过高斯分布生成了包含135个点的数据集中,其中x0是一个异常点,xi是一个正常的点。通过随机切分的方式,x0用了4次才被完全地孤立出来(图b),xi用了11次(图a),可见异常点的路径确实会比较短。那这到底是一次偶然还是必然呢?作者又重复大量做了这个实验,随着执行次数的增加,平均的路径长度逐渐收敛了(图c),x0为4.02,xi为12.82。
基于前面的想法给出两个更加正式的定义
Isolation Tree:树中的结果或者是一个叶子节点,或者是一个恰恰有两个子节点的内部节点,分割条件从属性q中随机取一个值p,左边小于p,右边大于p。其实就是二叉树。
Let T be a node of an isolation tree. T is either an external-node with no child, or an internal-node with one test and exactly two daughter nodes (Tl,Tr). A test consists of an attribute q and a split value p such that the test q < p divides data points into Tl and Tr.
Path Length:对于一个点x,h(x)表示从iTree根节点遍历到它的长度
h(x) of a point x is measured by the number of edges x traverses an iTree from the root node until the traversal is terminated at an external node.
Anomaly Score
那么能不能直接用h(x)来表示异常度呢?也不是不行,但是会有几个问题:1)h(x)是受数据集样本量的影响的,即数据量大且属性多的数据集应该要比数据量小属性少的数据集的树更深,也就是h(x)会更大;2) 针对每个数据集都需要确定最终异常点的阈值。所以需要找到一个办法来将异常分值映射到0-1区间,这样才能更好地使用。
The difficulty in deriving such a score from h(x) is that while the maximum possible height of iTree grows in the order of n, the average height grows in the order of log n.
由于iTree的结构和二叉搜索树(BST)完全相同,external node的估计平均h(x)等同于在BST中搜索失败。因此作者使用了[2]中给出的BST搜索失败的平均路径长度:
其中,
进而将数据x在数据集n中的异常分定义为:
,E(h(x))是x在iTree集合中的平均高度
异常分值有如下几个特性:
- 当数据x的平均高度接近c(n)时,异常分值趋近于0.5;E(h(x)) -> c(n), s -> 0.5
- 当数据x的平均高度接近于0时,异常分值趋近于1;E(h(x)) -> 0, s -> 1
- 当数据x的平均高度接近于n-1时,异常分值趋近于0;E(h(x)) -> n-1, s -> 0
并且异常分s与h(x)是单调的关系,如下图所示
总结一下就是:经过归一化后,越异常的点的分值越接近于1,越正常的点的分值越接近于0,同时随着异常度不断增加,分值也是不断增加的。但是需要注意的是,如果所有的点的取值都接近于0.5,则意味着数据集中可能没有什么异常点。
算法过程
iForest的高性能还得意于它的训练并不需要全部的数据集,作者给出了一个具体的案例,数据集由4096个实例组成,其中包含两个明显的异常组。通过在全量数据和一个随机抽取128个实例的子数据集上分别执行iForest发现,全局的AUC是0.67,而子集的AUC是0.91。
Since iForest does not need to isolate all of normal instances – the majority of the training sample, iForest is able to work well with a partial model without isolating all normal points and builds models using a small sample size.
构建一颗iTree的过程就是递归递执行随机切分,即每次选择一个属性,然后从最大和最小值之间随机选择一个切分点,将数据切分为左右子集。
构建iFroest就是构建n颗iTree的过程,其中每次训练的时候都是随机抽样数据集
预测的时候只需要在iForest中遍历数据点x,得到它的平均路径长度套到异常分公式中即可:
相关资料
- Data Structures and Algorithms with Object-Oriented Design Patterns in Java. Wiley, 1999.
- Isolation Forest
- spark开源库:github.com/titicaca/sp…