Isolation Forest算法原理详解

       本文只介绍原论文中的 Isolation Forest 孤立点检测算法的原理,实际的代码实现详解请参照我的另一篇博客:Isolation Forest算法实现详解

       或者读者可以到我的GitHub上去下载完整的项目源码以及测试代码(源代码程序是基于maven构建): https://github.com/JeemyJohn/AnomalyDetection

前言

       随着机器学习近年来的流行,尤其是深度学习的火热。机器学习算法在很多领域的应用越来越普遍。最近,我在一家广告公司做广告点击反作弊算法研究工作。想到了异常检测算法,并且上网调研发现有一个算法非常火爆,那就是本文要介绍的算法 Isolation Forest,简称 iForest

       南大周志华老师的团队在2010年提出一个异常检测算法Isolation Forest,在工业界很实用,算法效果好,时间效率高,能有效处理高维数据和海量数据,这里对这个算法进行简要总结。

1. iTree的构造

       提到森林,自然少不了树,毕竟森林都是由树构成的,看Isolation Forest(简称iForest)前,我们先来看看Isolation Tree(简称iTree)是怎么构成的,iTree是一种随机二叉树,每个节点要么有两个女儿,要么就是叶子节点,一个孩子都没有。给定一堆数据集D,这里D的所有属性都是连续型的变量,iTree的构成过程如下:

  1. 随机选择一个属性Attr;

  2. 随机选择该属性的一个值Value;

  3. 根据Attr对每条记录进行分类,把Attr小于Value的记录放在左女儿,把大于等于Value的记录放在右孩子;

  4. 然后递归的构造左女儿和右女儿,直到满足以下条件:

    • 传入的数据集只有一条记录或者多条一样的记录;

    • 树的高度达到了限定高度;

这里写图片描述

       iTree构建好了后,就可以对数据进行预测啦,预测的过程就是把测试记录在iTree上走一下,看测试记录落在哪个叶子节点。iTree能有效检测异常的假设是:异常点一般都是非常稀有的,在iTree中会很快被划分到叶子节点,因此可以用叶子节点到根节点的路径h(x)长度来判断一条记录x是否是异常点;对于一个包含n条记录的数据集,其构造的树的高度最小值为log(n),最大值为n-1,论文提到说用log(n)和n-1归一化不能保证有界和不方便比较,用一个稍微复杂一点的归一化公式:

S(x,n)=2h(x)c(n)
c(n)=2H(n1)(2(n1)/n)
H(k)=ln(k)+ξξ=0.5772156649

       s(x,n) 就是记录x在由n个样本的训练数据构成的iTree的异常指数, s(x,n) 取值范围为[0,1]异常情况的判断分以下几种情况:

  1. 越接近1表示是异常点的可能性高;

  2. 越接近0表示是正常点的可能性比较高;

  3. 如果大部分的训练样本的 s(x,n) 都接近于0.5,说明整个数据集都没有明显的异常值。

       由于是随机选属性,随机选属性值,一棵树这么随便搞肯定是不靠谱,但是把多棵树结合起来就变强大了;

2. iForest的构造

       iTree搞明白了,我们现在来看看iForest是怎么构造的,给定一个包含n条记录的数据集D,如何构造一个iForest。iForest和Random Forest的方法有些类似,都是随机采样一部分数据集去构造每一棵树,保证不同树之间的差异性,不过iForest与RF不同,采样的数据量 Psi 不需要等于n,可以远远小于n,论文中提到采样大小超过256效果就提升不大了,并且越大还会造成计算时间的上的浪费,为什么不像其他算法一样,数据越多效果越好呢,可以看看下面这两个个图:

这里写图片描述

       左边是原始数据,右边是采样了数据,蓝色是正常样本,红色是异常样本。可以看到,在采样之前,正常样本和异常样本出现重叠,因此很难分开,但我们采样之和,异常样本和正常样本可以明显的分开。

       除了限制采样大小 Ψ 以外,还要给每棵iTree设置最大高度 l=ceiling(log2Ψ),这是因为异常数据记录都比较少,其路径长度也比较低,而我们也只需要把正常记录和异常记录区分开来,因此只需要关心低于平均高度的部分就好,这样算法效率更高,不过这样调整了后,后面可以看到计算 h(x) 需要一点点改进,先看iForest的伪代码:

这里写图片描述

IForest构造好后,对测试进行预测时,需要进行综合每棵树的结果,于是

s(x,n)=2(E(h(x))c(n))

       E(h(x)) 表示记录x在每棵树的高度均值,另外 h(x) 计算需要改进,在生成叶节点时,算法记录了叶节点包含的记录数量,这时候要用这个数量 Size 估计一下平均高度, h(x) 的计算方法如下:

这里写图片描述

3. 对高维数据的处理

       在处理高维数据时,可以对算法进行改进,采样之后并不是把所有的属性都用上,而是用峰度系数Kurtosis挑选一些有价值的属性,再进行iTree的构造,这跟随机森林就更像了,随机选记录,再随机选属性。

4. 只使用正常样本

       这个算法本质上是一个无监督学习,不需要数据的类标,有时候异常数据太少了,少到我们只舍得拿这几个异常样本进行测试,不能进行训练,论文提到只用正常样本构建IForest也是可行的,效果有降低,但也还不错,并可以通过适当调整采样大小来提高效果。

5. 总结

  1. iForest具有线性时间复杂度。因为是ensemble的方法,所以可以用在含有海量数据的数据集上面。通常树的数量越多,算法越稳定。由于每棵树都是互相独立生成的,因此可以部署在大规模分布式系统上来加速运算。

  2. iForest不适用于特别高维的数据。由于每次切数据空间都是随机选取一个维度,建完树后仍然有大量的维度信息没有被使用,导致算法可靠性降低。高维空间还可能存在大量噪音维度或无关维度(irrelevant attributes),影响树的构建。对这类数据,建议使用子空间异常检测(Subspace Anomaly Detection)技术。此外,切割平面默认是axis-parallel的,也可以随机生成各种角度的切割平面,详见“On Detecting Clustered Anomalies Using SCiForest”。

  3. iForest仅对Global Anomaly 敏感,即全局稀疏点敏感,不擅长处理局部的相对稀疏点 (Local Anomaly)。目前已有改进方法发表于PAKDD,详见“Improving iForest with Relative Mass”。

  4. iForest推动了重心估计(Mass Estimation)理论发展,目前在分类聚类和异常检测中都取得显著效果,发表于各大顶级数据挖掘会议和期刊(如SIGKDD,ICDM,ECML)。

注意:目前我还没有发现有Java开源库实现了该算法。目前只有Python机器学习库scikit-learn的0.18版本对此算法进行了实现。而我的项目绝大多数都是Java实现的,因此我需要自己实现该算法。算法源码已实现并开源到我的GitHub上,读者可以下载源码并用IDEA集成开发环境直接打开项目,并运行测试程序以查看算法的检测效果:https://github.com/JeemyJohn/AnomalyDetection


对机器学习,人工智能感兴趣的小伙伴可以加我微信:JeemyJohn,我拉你进我的机器学习群(群里很多高手哦!),或者扫描二维码!当然你也可以关注我的公众号,点击链接:燕哥带你学算法公众号团队简介

这里写图片描述



参考文献:



有任何问题,加微信聊

这里写图片描述

<think>嗯,用户想了解孤立森林算法在数据填充和异常检测中的应用,特别是如何使用sklearn来实现。首先,我需要回忆一下孤立森林的基本原理。孤立森林是一种基于集成学习的异常检测方法,它通过构建多棵孤立树来隔离数据点,异常点因为特征与正常点差异大,所以会被更快地隔离,路径长度更短。 接下来,用户提到了数据填充和异常检测,这两个应用可能需要不同的处理步骤。在异常检测方面,sklearn中的IsolationForest类应该可以直接应用,我需要确认参数设置,比如n_estimators、contamination等,以及如何训练模型和预测结果。记得引用中的[^1]提到了IsolationForest的参数,比如n_estimators=100,max_samples='auto',这些可以作为示例代码的参考。 数据填充可能涉及检测到异常后如何处理缺失值或异常值。比如,先使用孤立森林识别异常,然后用均值、中位数或者其他方法填充。这里可能需要结合pandas来处理数据,替换异常值为NaN后再进行填充。引用中的[^3]提到了计算异常比例,可能是在处理后的数据统计中使用。 用户可能需要具体的代码示例,所以需要写出导入模型、创建实例、训练预测的步骤。在异常检测部分,预测结果返回-1和1,需要转换为0和1以便理解。数据填充部分则需要展示如何标记异常,替换为NaN,再用简单方法填充。 还要注意用户提到的引用内容,确保在回答中正确引用。比如,引用关于IsolationForest的参数,引用[^2]关于算法局限性,引用[^3]关于数据处理步骤。需要将这些引用自然地融入到回答中,比如在参数解释部分引用[^1],在讨论局限性时引用。 可能用户的问题还包括如何调参或评估模型性能,但用户主要问的是实现和应用,所以重点放在代码示例和应用步骤上。同时,生成的相关问题需要考虑用户可能进一步想知道的内容,比如参数调优、算法优缺点、结合其他技术的方法等。 最后,确保回答结构清晰,分步骤说明,代码正确,并且引用标记正确。需要检查LaTeX格式是否正确,比如变量用$...$,独立公式用$$...$$,但在这个问题中可能数学公式不多,但如果有的话要注意格式。不过目前的问题更侧重代码和应用,可能数学内容较少,但如果有提到路径长度或异常分数,可能需要用LaTeX表达。</think>### 孤立森林算法实现与应用详解(基于sklearn) #### 1. 孤立森林的核心原理 孤立森林(Isolation Forest)是一种基于树结构的无监督异常检测算法,通过构建多棵“孤立树”(iTree)来隔离数据点。其核心思想是:**异常点因特征与正常数据差异显著,会被更快地隔离到树的叶子节点**,路径长度更短。算法的时间复杂度为$O(n \log n)$,适合高维大数据场景。 --- #### 2. 异常检测实现步骤(sklearn示例) ```python from sklearn.ensemble import IsolationForest import pandas as pd # 数据加载 data = pd.read_csv('data.csv') X = data[['feature1', 'feature2']] # 初始化模型(关键参数说明见下文) model = IsolationForest( n_estimators=100, # 树的数量(引用) contamination=0.05, # 异常比例估计 max_samples='auto', # 每棵树采样样本数 random_state=42 ) # 训练与预测 model.fit(X) predictions = model.predict(X) # 返回1(正常)/-1(异常) # 转换为0-1标签(0=异常,1=正常) data['is_normal'] = [1 if x == 1 else 0 for x in predictions] ``` **关键参数说明**: - `n_estimators`:增加树的数量提升稳定性(但可能过拟合)[^1] - `contamination`:需结合实际场景调整(引用[^3]中通过`outlier_count/normal_count`计算比例) - `max_features`:建议设置为特征维度数(默认1.0表示全特征) --- #### 3. 数据填充应用场景 孤立森林可用于**异常值检测后的数据修复**: ```python # 标记异常点为NaN data.loc[data['is_normal'] == 0, 'value'] = None # 使用均值填充(或中位数/插值) mean_value = data['value'].mean() data['value_filled'] = data['value'].fillna(mean_value) ``` --- #### 4. 算法局限性及改进方向(引用) 1. **高维稀疏数据效果下降**:可通过特征选择优化 2. **局部密集异常检测困难**:结合LOF(局部离群因子)算法 3. **参数敏感性问题**:使用网格搜索验证最佳参数组合 ---
评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值