孤立森林:大数据背景下的最佳异常检测算法之一

简介: 孤立森林:大数据背景下的最佳异常检测算法之一

孤立森林或“iForest”是一个非常漂亮和优雅简单的算法,可以用很少的参数来识别异常。原始的论文对广大的读者来说是容易理解的,并且包含了很少的数学知识。在这篇文章中,我将解释为什么iForest是目前最好的大数据异常检测算法,提供算法的总结,算法的历史,并分享一个代码实现。

640.jpg

为什么iForest是目前最好的大数据异常检测算法

iForest有着基于ROC性能和精度的一流的综合性能。iForest在各种数据集上的性能均优于大多数其他异常值检测(OD)算法。我从Python离群值检测包(PyOD)的作者那里获取了基准数据,并在Excel中应用了行向绿-红渐变条件格式。深绿色表示数据集的最佳算法,深红色表示性能最差的算法:

640.png

我们看到,iForest在大多数数据集中均处于领先地位,如我所计算的均值,中位数和标准差行的颜色所示。iForest的相同优异结果也适用于N次精度:

640.png

可扩展性。iForest是性能最快的算法。预期在所有数据集中,基于PCA和基于直方图的离群值(HBOS)都更快。k最近邻(KNN)慢得多,并且随着更多的观测值N而扩展得非常厉害。

我已经成功建立了孤立森林,其中包含在集群环境中以分钟为单位的包含100M个观测值和36列的数据集。这样的数据如果使用sk-learn的KNN()速度上简直无法忍受。

640.png

算法要点总结

一下可以认为是10页原始论文的总结,如果不想深入研究,看一下要点就可以了。

  1. 大多数其他离群值检测(OD)算法试图构建“正常”实例的配置文件,然后标记不符合该配置文件的实例。iForest通过利用异常的固有特性明确地孤立异常记录:它们的协变量集合具有不寻常的值。
  2. 由于计算量大,现有方法仅限于低维数据和小数据大小。举例:尝试对大数据使用sklearn.neighbor.KNeighborsClassifier吗?
  3. 另外,iForest具有低开销的特点。细节:外部节点的数量为n,因为每个观测值n都是独立的。内部节点的总数显然为n-1,而节点的总数为2n-1。因此,我们了解了为什么内存需求是有界的并且随n线性增长。
  4. 孤立树节点定义:T是无子外部节点或具有一个测试且恰好有两个子节点(Tₗ,Tᵣ)的内部节点。要构建iTree,我们通过随机选择属性q和拆分值p递归地将X划分为:(i)树达到高度限制,(ii)所有观测值都孤立在其自己的外部节点上,或者(iii) 所有数据的所有属性值都相同。
  5. 路径长度。观测值x的路径长度h(x)通过从根节点横穿iTree直到横向终止于外部节点的边数x来度量。E(h(x))是来自孤立树集合的h(x)的平均值。可以从平均路径长度E(h(x))得出异常分数s(x,n):s(x,n)= 2 ^ [-E(h(x))/ c(n )]。基本上,s和E(h(x))之间存在单调关系(有关详细信息,请参见附录末尾)。我不会涉及术语c(n),所以我可以保持简短,但是对于任何给定的静态数据集来说,它都是常数。
  6. 仅要求用户设置两个变量:要构建的树数和子采样大小。作者利用生成的高斯分布数据进行了实验,这些实验表明如何在很少的树和较小的子样本的情况下相对快速地实现平均路径长度的收敛。
  7. 小的次抽样(样本的样本)解决了沼泽化和掩蔽问题。对于异常检测而言,输入数据太大而造成了沼泽化和掩蔽。沼泽化是指将“正常”观测结果误认为“异常”观测结果,因为它被异常所包围,而掩蔽则相反。换句话说,当为一棵树提供包含大部分异常的样本时,一个正常的数据点可能看起来异常。作者用x光检查的数据提供了这种现象的例子。
  8. 小的子样本允许每个孤立树被特殊化,因为每个子样本包含一组不同的异常或甚至没有异常
  9. iForest不依赖于任何距离或基于密度的测量来识别异常,所以它速度快,计算成本低,这就引出了下一个问题
  10. 线性时间复杂度,O(n)通俗地说,这意味着运行时间随着输入的大小线性增加。

640.png

算法的历史

一个伟大的新想法和更广泛的采纳之间可能有几十年的滞后性。例如,logistic 函数在1845年被发现,在1922年被重新发现,现在被现代数据科学家用于logistic 回归。近几十年来,一个新想法和它被广泛采用之间的滞后时间已经缩短了,但这仍然是一个有争议的很长的时间。iForest于2008年首次共享,直到2018年底才发布具有商业可行性的应用程序!时间表如下:

12/2008 - iForest发布的原始论文

07/2009 - iForest作者最后一次修改他们的代码实现代码

10/2018- h2o团队为R和Python用户提供iForest代码

01/2019 - PyOD发布面向Python用户的离群点检测(OD)工具包代码

08/2019 - LinkedIn工程团队发布Spark/Scala实现iForest代码

代码的实现

由于本文是关于大数据的,所以假设是AWS集群环境。代码脚手架(QA对象的代码,调试等等)大多被省略了。

我发现iForest可以轻松快速地处理750万行和36个特性,按分钟的顺序完成计算。

Python (h2o):

importh2o#h2oautomateddatacleaningwellformydatasetimportpkg_resources###################################################################printpackages+versionsfordebugging/futurereproducibility###################################################################dists= [dfordinpkg_resources.working_set] #Filteroutdistributionsyoudon't care about and use.dists.reverse()dists################################################################### initialize h2o cluster and load data##################################################################h2o.init() # http://docs.h2o.ai/h2o/latest-stable/h2o-r/docs/reference/h2o.init.htmlimport pyarrow.parquet as pq # allow loading of parquet filesimport s3fs                 # for working in AWS s3s3 = s3fs.S3FileSystem()df = pq.ParquetDataset('s3a://datascience-us-east-1/anyoung/2_processedData/stack_parquetFiles', filesystem=s3).read_pandas().to_pandas()# check input data loaded correctly; pretty print .shapeprint('('+'; '.join(map('{:,.0f}'.format,
df.shape)) +')')#ifyouneedtosampledatadf_samp_5M=df.sample(n=5000000, frac=None, replace=False, weights=None, random_state=123, axis=None)#convertPandasDataFrameobjecttoh2oDataFrameobjecthf=h2o.H2OFrame(df)#dropprimarykeycolumnhf=hf.drop('referenceID', axis=1) #referenceIDcauseserrorsinsubsequentcode#youcanomitrowswithnasforafirstpasshf_clean=hf.na_omit()#prettyprint .shapewiththousandscommaseparatorprint('('+'; '.join(map('{:,.0f}'.format,
hf.shape)) +')')fromh2o.estimatorsimportH2OIsolationForestEstimatorfromh2o.estimatorsimportH2OIsolationForestEstimatorfullX= ['v1',
'v2',
'v3'      ]#splith2oDataFrameinto80/20train/testtrain_hf, valid_hf=hf.split_frame(ratios=[.8], seed=123)#specifyiForestestimatormodelsisolation_model_fullX=H2OIsolationForestEstimator(model_id="isolation_forest_fullX.hex", seed=123)
isolation_model_fullX_cv=H2OIsolationForestEstimator(model_id="isolation_forest_fullX_cv.hex", seed=123)#trainiForestmodelsisolation_model_fullX.train(training_frame=hf, x=fullX)
isolation_model_fullX_cv.train(training_frame=train_hf, x=fullX)#savemodels (haven't figured out how to load from s3 w/o permission issues yet)modelfile = isolation_model_fullX.download_mojo(path="~/", get_genmodel_jar=True)print("Model saved to " + modelfile)# predict modelspredictions_fullX = isolation_model_fullX.predict(hf)# visualize resultspredictions_fullX["mean_length"].hist()

640.png

如果你的数据具有想要用iForest验证的标签,那么您可以比较正常实例集与异常实例集的分布,并与原始数据集进行进一步的推断。例如,你可以通过原始数据集中不同的特征组合来查看计数,如下所示:

N=df.count()
df[['v1', 'v2', 'id']].groupby(['v1', 'v2']).count() /Ndf[['v1', 'v3', 'id']].groupby(['v1', 'v3']).count() /N...

并与iForest确定的正常/异常实例集进行比较,如下图所示:

###################################################################columnbindpredictionsfromiForesttotheoriginalh2oDataFrame##################################################################hf_X_y_fullX=hf.cbind(predictions_fullX)
###################################################################Sliceusingabooleanmask. Theoutputdatasetwillincluderows#withcolumnvaluemeetingcondition##################################################################mask=hf_X_y_fullX["label"] ==0hf_X_y_fullX_0=hf_X_y_fullX[mask,:]
mask=hf_X_y_fullX["label"] ==1hf_X_y_fullX_1=hf_X_y_fullX[mask,:]
###################################################################Filtertoonlyincluderecordsthatareclearlynormal##################################################################hf_X_y_fullX_ml7=hf_X_y_fullX[hf_X_y_fullX['mean_length'] >=7]
hf_X_y_fullX_0_ml7=hf_X_y_fullX_1[hf_X_y_fullX_0['mean_length'] >=7]
hf_X_y_fullX_1_ml7=hf_X_y_fullX_3[hf_X_y_fullX_1['mean_length'] >=7]
###################################################################ConverttoPandasDataFrameforeasiercounting/familiarity##################################################################hf_X_y_fullX_ml7_df=h2o.as_list(hf_X_y_fullX_ml7, use_pandas=True)
hf_X_y_fullX_0_ml7_df=h2o.as_list(hf_X_y_fullX_0_ml7, use_pandas=True)
hf_X_y_fullX_1_ml7_df=h2o.as_list(hf_X_y_fullX_1_ml7, use_pandas=True)
###################################################################Lookatcountsbycombinationsofvariablelevelsforinference##################################################################hf_X_y_fullX_ml7_df[['v1', 'v2', 'id']].groupby(['v1', 'v2']).count()
hf_X_y_fullX_0_ml7_df=h2o.as_list(hf_X_y_fullX_0_ml7, use_pandas=True)
#Repeataboveforanomalousrecords:###################################################################Filtertoonlyincluderecordsthatareclearlyanomalous##################################################################hf_X_y_fullX_ml3=hf_X_y_fullX[hf_X_y_fullX['mean_length'] <3]
hf_X_y_fullX_0_ml3=hf_X_y_fullX_1[hf_X_y_fullX_0['mean_length'] <3]
hf_X_y_fullX_1_ml3=hf_X_y_fullX_3[hf_X_y_fullX_1['mean_length'] <3]
###################################################################ConverttoPandasDataFrameforeasiercounting/familiarity##################################################################hf_X_y_fullX_ml3_df=h2o.as_list(hf_X_y_fullX_ml3, use_pandas=True)
hf_X_y_fullX_0_ml3_df=h2o.as_list(hf_X_y_fullX_0_ml3, use_pandas=True)
hf_X_y_fullX_1_ml3_df=h2o.as_list(hf_X_y_fullX_1_ml3, use_pandas=True)

完成所有这些,并数据导出到Excel中,以快速生成一些累积分布函数,像这样:

640.png

参考文献

F. T. Liu, K. M. Ting, and Z.-H. Zhou. Isolation forest. In: Proceedings of the 8th IEEE International Conference on Data Mining (ICDM’08), Pisa, Italy, 2008, pp.413–422. [code] This paper won the Theoretical/Algorithms Runner-Up Best Paper Award at IEEE ICDM’08

Zhao, Y., Nasrullah, Z. and Li, Z., 2019. PyOD: A Python Toolbox for Scalable Outlier Detection. Journal of machine learning research (JMLR), 20(96), pp.1–7.

附录

算法要点/小结,第5点具体内容:

E(h(x))→c(n), s→0.5(观测不明显异常)

当E(h(x))→0,s→1(异常)

当E(h(x))→n−1,s→0(不是异常)

所以用这篇论文的话来总结一下上面的内容:

(a)如果实例返回s非常接近1,那么它们肯定是异常的,

(b)如果实例的s远远小于0.5,那么它们被视为正常实例是相当安全的,并且

(c)如果所有实例返回s≈0.5,那么整个样本实际上没有任何明显的异常。

有助于说明异常得分、s和平均路径长度E(h(x))之间关系的图表

相关实践学习
简单用户画像分析
本场景主要介绍基于海量日志数据进行简单用户画像分析为背景,如何通过使用DataWorks完成数据采集 、加工数据、配置数据质量监控和数据可视化展现等任务。
SaaS 模式云数据仓库必修课
本课程由阿里云开发者社区和阿里云大数据团队共同出品,是SaaS模式云原生数据仓库领导者MaxCompute核心课程。本课程由阿里云资深产品和技术专家们从概念到方法,从场景到实践,体系化的将阿里巴巴飞天大数据平台10多年的经过验证的方法与实践深入浅出的讲给开发者们。帮助大数据开发者快速了解并掌握SaaS模式的云原生的数据仓库,助力开发者学习了解先进的技术栈,并能在实际业务中敏捷的进行大数据分析,赋能企业业务。 通过本课程可以了解SaaS模式云原生数据仓库领导者MaxCompute核心功能及典型适用场景,可应用MaxCompute实现数仓搭建,快速进行大数据分析。适合大数据工程师、大数据分析师 大量数据需要处理、存储和管理,需要搭建数据仓库?学它! 没有足够人员和经验来运维大数据平台,不想自建IDC买机器,需要免运维的大数据平台?会SQL就等于会大数据?学它! 想知道大数据用得对不对,想用更少的钱得到持续演进的数仓能力?获得极致弹性的计算资源和更好的性能,以及持续保护数据安全的生产环境?学它! 想要获得灵活的分析能力,快速洞察数据规律特征?想要兼得数据湖的灵活性与数据仓库的成长性?学它! 出品人:阿里云大数据产品及研发团队专家 产品 MaxCompute 官网 https://www.aliyun.com/product/odps&nbsp;
目录
相关文章
|
7月前
|
机器学习/深度学习 数据采集 算法
解码大数据:模型与算法的奥秘和应用
解码大数据:模型与算法的奥秘和应用
|
5月前
|
机器学习/深度学习 算法
基于相空间重构的混沌背景下微弱信号检测算法matlab仿真,对比SVM,PSO-SVM以及GA-PSO-SVM
基于相空间重构的混沌背景下微弱信号检测算法matlab仿真,对比SVM,PSO-SVM以及GA-PSO-SVM
|
7月前
|
运维 监控 算法
应用异常检测算法提升上网行为管理软件的安全性
异常检测算法在上网行为管理软件中真是大有用途,不过也不是没有一些小挑战。大家都知道的,上网行为管理软件的目标是看管和掌控网上用户的行径,就是要确保网络稳如狗,合规规规矩矩,资源还能玩得溜。咱们这领域里,异常检测算法的点子用法是找出那些潜伏的安全威胁,打压不合规的事情,还有就是揪出网络上的怪现象,然后惩罚掉。
104 2
|
4月前
|
分布式计算 算法 搜索推荐
阿里巴巴内部:全技术栈PPT分享(架构篇+算法篇+大数据)
我只截图不说话,PPT大全,氛围研发篇、算法篇、大数据、Java后端架构!除了大家熟悉的交易、支付场景外,支撑起阿里双十一交易1682亿元的“超级工程”其实包括以下但不限于客服、搜索、推荐、广告、库存、物流、云计算等。 Java核心技术栈:覆盖了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。 大数据:Spark、Hadoop
|
4月前
|
消息中间件 存储 算法
【云计算与大数据技术】数据编码LZSS算法、Snappy压缩库及分布式通信系统的讲解(图文解释 超详细)
【云计算与大数据技术】数据编码LZSS算法、Snappy压缩库及分布式通信系统的讲解(图文解释 超详细)
73 0
|
4月前
|
存储 分布式计算 大数据
【云计算与大数据技术】大数据概念和发展背景讲解(图文解释 超详细)
【云计算与大数据技术】大数据概念和发展背景讲解(图文解释 超详细)
172 0
|
4月前
|
存储 算法 搜索推荐
大数据管理的重要思想和算法总结----排序(上)
大数据管理的重要思想和算法总结----排序(上)
41 0
|
7月前
|
分布式计算 算法 搜索推荐
阿里巴巴内部:全技术栈PPT分享(架构篇+算法篇+大数据)
我只截图不说话,PPT大全,氛围研发篇、算法篇、大数据、Java后端架构!除了大家熟悉的交易、支付场景外,支撑起阿里双十一交易1682亿元的“超级工程”其实包括以下但不限于客服、搜索、推荐、广告、库存、物流、云计算等。 Java核心技术栈:覆盖了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。 大数据:Spark、Hadoop
|
8月前
|
机器学习/深度学习 人工智能 算法
实用!50个大厂、987页大数据、算法项目落地经验教程合集
大数据、算法项目在任何大厂无论是面试还是工作运用都是非常广泛的,我们精选了50个百度、腾讯、阿里等大厂的大数据、算法落地经验甩给大家,千万不要做收藏党哦,空闲时间记得随时看看! 如果你没有大厂项目经验,对大厂算法、大数据的项目运用不了解建议你看看!
|
9月前
|
运维 算法 数据挖掘
自主异常检测算法(Matlab代码实现)
自主异常检测算法(Matlab代码实现)

热门文章

最新文章