赞
踩
目录
4 特点
现有的异常检测方法主要是通过对正常样本的描述,给出一个正常样本在特征空间中的区域,对于不在这个区域中的样本,视为异常。这些方法的主要缺点是,异常检测器只会对正常样本的描述做优化,而不会对异常样本的描述做优化,这样就有可能造成大量的误报,或者只检测到少量的异常。
异常的两个特点:异常数据只占很少量、异常数据特征值和正常数据差别很大。
孤立森林,不再是描述正常的样本点,而是要孤立异常点,由周志华教授等人于2008年在第八届IEEE数据挖掘国际会议上提出,之后又于2012年提出了改进版本。
先了解一下该算法的动机。目前学术界对异常(anomaly detection)的定义有很多种,在孤立森林(iForest)中,异常被定义为“容易被孤立的离群点 (more likely to be separated)”,可以将其理解为分布稀疏且离密度高的群体较远的点。 在特征空间里,分布稀疏的区域表示事件发生在该区域的概率很低,因而可以认为落在这些区域里的数据是异常的。孤立森林是一种适用于连续数据(Continuous numerical data)的无监督异常检测方法,即不需要有标记的样本来训练,但特征需要是连续的。对于如何查找哪些点容易被孤立(isolated),iForest使用了一套非常高效的策略。在孤立森林中,递归地随机分割数据集,直到所有的样本点都是孤立的。在这种随机分割的策略下,异常点通常具有较短的路径。
具体来说,该算法利用一种名为孤立树的二叉搜索树结构来孤立样本。由于异常值的数量较少且与大部分样本的疏离性,因此,异常值会被更早的孤立出来,也即异常值会距离的根节点更近,而正常值则会距离根节点有更远的距离。此外,相较于LOF,K-means等传统算法,孤立森林算法对高纬数据有较好的鲁棒性。
从下图我们可以直观的看到,相对更异常的只需要4次切割就从整体中被分离出来,而更加正常的点经过了11次分割才从整体中分离出来。这也体现了孤立森林算法的基本思想。
我们先给出孤立树(Isolation Tree)和样本点在孤立树中的路径长度的定义。
孤立树:若为孤立树的一个节点,存在两种情况:没有子节点的外部节点,有两个子节点和一个test的内部节点。在的test由一个属性 q 和一个分割点 p 组成,的点属于,反之属于。
样本点在孤立树中的路径长度:样本点从的根节点到叶子节点经过的边的数量。
下面,我们来详细介绍孤立森林算法。该算法大致可以分为两个阶段,第一个阶段我们需要训练出颗孤立树,组成孤立森林。随后我们将每个样本点带入森林中的每棵孤立树,计算平均高度,之后再计算每个样本点的异常值分数。
(1)第一阶段
(2)第二阶段
Step1: 对于每一个数据点 ,令其遍历每一颗孤立树,计算点在森林中的平均高度 ,对所有点的平均高度做归一化处理。异常值分数的计算公式如下所示:
其中,
S(x,n) 就是记录x在n个样本的训练数据构成的iTree的异常指数,S(x,n)取值范围为[0,1]。
就是记录 x 在由 n 个样本的训练数据构成 iTree 的异常指数,取值范围为[0, 1],异常情况的判断分以下几种情况
如果是随机选属性,随机选属性值,一棵树这么随机选肯定不行,但是把多棵树结合起来就变的强大了。
4个测试样本遍历一棵iTree的例子如下:
可以看到d最有可能是异常,因为其最早就被孤立(isolated)了。
IForest构造好之后,对测试进行预测,需要进行综合每棵树的结果,于是 PathLength 表示记录 x 在每棵树的高度均值,另外计算需要改进,在生成叶子节点时,算法记录了叶子节点包含的记录数量,这时候需要用这个数量估计一下平均高度的,其计算方法如下:
在处理高维数据时,可以对算法进行改进,采样之后并不是把所有的属性都用上,而是用峰度系数Kurtosis挑选一些有价值的属性,再进行iTree的构造,这跟随机森林就更像了,随机选记录,再随机选属性。
- # _*_coding:utf-8_*_
- import numpy as np
- import matplotlib.pyplot as plt
- from sklearn.ensemble import IsolationForest
-
- rng = np.random.RandomState(42)
-
- # Generate train data
- X = 0.3 * rng.randn(100, 2)
- X_train = np.r_[X + 2, X - 2]
- X = 0.3 * rng.randn(20, 2)
- X_test = np.r_[X + 2, X - 2]
- X_outliers = rng.uniform(low=-4, high=4, size=(20, 2))
-
- # fit the model
- clf = IsolationForest(max_samples=100,
- random_state=rng, contamination='auto')
- clf.fit(X_train)
- y_pred_train = clf.predict(X_train)
- y_pred_test_1 = clf.predict(X_test)
- y_pred_test = clf.predict(X_outliers)
- print(y_pred_test_1)
-
- xx, yy = np.meshgrid(np.linspace(-5, 5, 50), np.linspace(-5, 5, 50))
- Z = clf.decision_function(np.c_[xx.ravel(), yy.ravel()])
- Z = Z.reshape(xx.shape)
-
- plt.title("IsolationForest")
- plt.contourf(xx, yy, Z, camp=plt.cm.Blues_r)
- b1 = plt.scatter(X_train[:, 0], X_train[:, 1], c='white',
- s=20, edgecolor='k')
- b2 = plt.scatter(X_test[:, 0], X_test[:, 1], c='green',
- s=20, edgecolor='k')
- c = plt.scatter(X_outliers[:, 0], X_outliers[:, 1], c='red',
- s=20, edgecolor='k')
- plt.axis('tight')
- plt.xlim((-5, 5))
- plt.ylim((-5, 5))
- plt.legend([b1, b2, c],
- ["training observations",
- "new regular observations", "new abnormal observations"],
- loc="upper left")
- plt.show()
Isolation Forest 算法主要有两个参数:一个是二叉树的个数;另一个是训练单棵ITree时候抽取样本的数目。实验表明,当设定为100棵树,抽样样本为256条的时候,iForest 在大多数情况下就可以取得不错的效果。这也体现了算法的简单,高效。
Isolation Forest 是无监督的异常检测算法,在实际应用中,并不需要黑白标签。需要注意的是:
iForest (Isolation Forest)孤立森林 异常检测 入门篇:iForest (Isolation Forest)孤立森林 异常检测 入门篇 - 简书
异常检测概览——孤立森林 效果是最好的:异常检测概览——孤立森林 效果是最好的 - bonelee - 博客园
孤立森林(Isolation Forest):孤立森林(Isolation Forest)_extremebingo的博客-CSDN博客_孤立森林
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。