Isolation Forest

异常是指与普通实例具有不同数据特征的数据模式。
大多数现有的基于模型的异常检测方法构建了正常实例的概要,然后将不符合正常概要的实例标识为异常。种方法的两个主要缺点是:(i)异常检测器被优化以分析正常情况,但未针对异常情况进行优化 - 因此,异常检测的结果可能不如预期的那么好导致过多的误报(正常情况被识别为异常)或检测到的异常太少; (ii)许多现有方法由于其高计算复杂性而受限于低维数据和小数据大小。

异常的定量属性:
他们是由少数实例和少数组成的少数
它们的属性值与普通实例的属性值非常不同

iForest具有线性时间复杂度,具有低常量和低内存要求

异常更容易受到隔离,因此路径长度较短

正常点通常需要隔离更多的分区。对于异常点也是如此,其通常需要较少的分区来隔离

通过随机选择属性然后随机选择来生成分区所选属性的最大值和最小值之间的拆分值。由于递归分区可以由树结构表示,因此隔离点所需的分区数等于从根节点到终止节点的路径长度

异常检测的任务是提供反映异常程度的排名。因此,一种检测异常的方法是根据数据点的路径长度或异常分数对数据点进行排序

路径长度定义:
点x的路径长度h(x)是通过从根节点遍历iTree的边数直到遍历在外部节点处终止来测量的。

异常得分:
\(s(x,n)=2^{-\frac{E(h(x))}{c(n)}}\)
其中\(c(n)=2H(n-1)-(2(n-1)/n)\)
\(H(n)=ln(n)+0.5772156649\)
E(h(x))是期望路径长度
c(n)是树平均路径长度
通常如果s<0.6,则认为是异常点

淹没指的是将正常情况识别为异常。当正常情况太接近异常时,分离异常所需的分区数量会增加

掩蔽是存在太多隐藏自己存在的异常现象。当异常群集较大且密集时,它还会增加分区数以隔离每个异常。

淹没和掩蔽都是由于异常检测的数据太多而导致的。隔离树的独特特性允许iForest通过子采样建立部分模型,从而顺便减轻了淹没和掩蔽的影响

使用iForest进行异常检测是一个两阶段过程。第一个(训练)阶段使用训练集的子样本构建隔离树。第二个(测试)阶段通过隔离树传递测试实例,以获得每个实例的异常分数。

训练iForest的复杂度为\(O(t\psi log \psi)\)
\(\psi\)是子样本数量,通常设置为256
t是tree的数量,通常设置为100

Algorithm 1:iForest(X,t \(\psi\))
Input: X-input data,t-number of trees,\(\psi\)-sub-sampling size
output: a set of t iTrees

1.Initialize Forest
2.set height limit \(l = ceiling(log_2 \psi)\)
3.for i = 1 to t do
\(X'<-sample(X,\psi)\)
Forest<-Forest\(\cup\)iTree(X',0,l)
4.end for
5.return Forest

Algorithm 2:iTree(X,e,l)
Input:X-input data,e-current tree height ,l-height limit
Output:an iTree

  1. if e>=l or |X|<=1 then
  2. return exNode
  3. else
  4. let Q be a list of attributes in X
  5. randomly select an attributes in q \(\in\)Q
  6. randomly select an split point p from max and min values of attribute q in X
  7. \(X_l<-filter(X,q<p)\)
  8. \(X_r<-filter(X,q>=p)\)
  9. return inNode{
  10. Left<-iTree(\(X_l\),e+1,l)
  11. Right<-iTree(\(X_r\),e+1,l)
  12. SplitAtt<-q
  13. SplitValue<-p}
  14. end if

Algorithm 3:PathLength(x,T,e)
Inputs:x-an instance ,T-an iTree,e-current path length;
to be initalized to zero when first called
Output:path length of x

1.if T in an external node then
2. return e+c(T.size)
3. end if
4. a<-T.splitAtt
5. if \(x_a<T.splitValue then\)
6. return PathLength(x,T.left,e+1)
7. else{\(x_a>=T.splitValue\)}
8. return PathLength(x,T.right,e+1)
9. end if

posted @ 2018-12-01 16:05  blog_hfg  阅读(454)  评论(0)    收藏  举报