前言

最近阅读了spark mllib(版本:spark 1.3)中Random Forest的实现,发现在分布式的数据结构上实现迭代算法时,有些地方与单机环境不一样。单机上一些直观的操作(递归),在分布式数据上,必须进行优化,否则I/O(网络,磁盘)会消耗大量时间。本文整理spark随机森林实现中的相关技巧,方便后面回顾。

 

随机森林算法概要

随机森林算法的详细实现和细节,可以参考论文Breiman 2001。这里简单说说大体思路,方便理解代码。

随机森林是一个组装(ensemble model)模型,内部的模型使用决策树。基本思想是生成很多很多决策树(构成森林),最后由这些决策数一起投票决定最终结果。生成树的过程中,从行和列两个方向添加随机过程。行方向,在构建每棵树前,使用有放回抽样(称为Bootstrapping),得到训练数据。列方向,每次选择切分点时,对feature进行无放回随机抽样,得到一个feature子集,在当前节点上,只使用这些子集对应的数据计算最优切分点。这也是为什么此算法称为随机森林,是不是很直观。相比于单一决策树,随机森林有以下一些优点:

  1. 结果比较稳定,不容易出现过拟合;
  2. Out-Of-Bag error评估模型效果,无需交叉检验;
  3. 可得到feature重要性。

当然,为了得到上面的优点,必须付出计算开销作为代价。在单机时代,使用随机森林(R或scikit-learn)往往成本很高,但是现在有了spark,使得大规模,分布式迭代计算成为了可能,所以在spark上运用随机森林是技术发展的必然结果!

 

Spark实现优化

spark在实现随机森林时,采用了下面几个优化策略:

  1. 切分点抽样
  2. feature装箱(bin)
  3. 分区统计
  4. 逐层计算(level-wise)

使用这些策略,原因在于RDD的数据时分布在不同服务器上,为了避免过多的I/O,必须在原始算法上做出一些优化,否则执行时间可能难以接受。下面分别详细讨论这三个优化策略。

 

切分点抽样

此优化主要针对连续变量。先回忆一下一般的决策树是如何对连续变量进行切分点选择的。一般是先对feature进行排序,然后选取相邻两个数据之间的点作为切分点。如果在RDD上执行这个操作,不可避免会使用shuffle过程,此过程会带来大量的网络通讯。而且,一般RDD上的数据都很大,少则几百万,多则几亿到几十亿,甚至更多。在这样的数量级上进行排序操作,想想也是醉了。所以,为了避免排序操作,mllib通过抽样的方法,在样本上进行排序,并且根据样本,获取切分点。据spark团队反馈,使用此策略虽然牺牲了部分精度,但是在实际运用过程中,并没有带来过多的影响,模型效果可以接受。

 

feature装箱

根据抽样,得到切分点后,接下来是对feature进行装箱操作,箱子就是由相邻的样本切分点构成。箱子的个数是非常小的,一般实际中采用30个左右。计算每个箱子中不同种类的占比,可以很快计算出最优切分点。

举个例子,参考上面的示例数据,第一行是每个切分点的比例统计。基于上面的数据,可能生成3中切分情况,分别有棕,红和绿色三行表示。如果需要计算棕色的切分情况,只需要按照第一行的组合方式,就可以很快的计算所出来。

 

分区统计

RDD分区中装箱数据单独统计后,可以通过reduce将每个分区的数据合并,得到总体的装箱数据(通过mapPartition实现分区统计)。正是由于装箱统计数据可以合并,所以可以很好的适应分布式数据环境,最后需要合并的数据也只是一些统计数据,不会带来很大的网络通讯开销。

 

逐层计算

单机版本的决策数生成过程是通过递归调用(本质上是深度优先)的方式构造树,在构造树的同事,需要移动数据,将同一个子节点的数据移动到一起。此方法在分布式数据结构上无法有效的执行,而且也无法执行,因为数据太大,无法放在一起,所以在分布式存储。mlib采用的策略是逐层构建树节点(本质上是广度优先),这样遍历所有数据的次数等于所有树的最大层数。每次遍历时,只需要计算每个节点所有feature的装箱统计参数,遍历完后,根据节点装箱统计量,决定是否切分,以及如何切分。

 

以上就是spark mllib实现的随机森林的关键技巧。当然还有很多实现细节这里没有描述,不过如果理解了这些技巧,对阅读spark mllib随机森林源代码会有很大帮助,希望对读者有用。

 

Spark Random Forest实现的不足

截止到spark 1.3,mllib的随机森林仍然不支持OOB error和variable importance的支持,也有一些网友在spark社区咨询此问题,但是目前没有得到官方的回应。希望后面,spark可以支持此特性。

 

应用案例

目前,在网络游戏流失预测的场景下,使用spark随机森林模型(1000棵树)和单机c50模型做了对比试验。试验中覆盖5款不同类型的游戏,共执行608轮,试验周期跨度为4个月。采用了相同的数据,由于单机数据量计算限制,C50使用了10%的采样建模,而spark使用了全量数据(计算能力秒杀)。试验结果是随机森林的模型效果明显优于C50。F1值有37%的提升,而F2(召回率优先)提升度高达72%。

提升可能的原因有两个:

1 随机森林模型效果确实优于C50

2 随机森林建模数据量有质的飞跃,导致性能提升

 

参考资料

  1. Spark源代码
  2. Spark峰会关于分布式决策树实现的分享

Spark随机森林实现学习的更多相关文章

  1. Spark随机森林实战

    package big.data.analyse.ml.randomforest import org.apache.spark.ml.Pipeline import org.apache.spark ...

  2. spark 随机森林算法案例实战

    随机森林算法 由多个决策树构成的森林,算法分类结果由这些决策树投票得到,决策树在生成的过程当中分别在行方向和列方向上添加随机过程,行方向上构建决策树时采用放回抽样(bootstraping)得到训练数 ...

  3. python spark 随机森林入门demo

    class pyspark.mllib.tree.RandomForest[source] Learning algorithm for a random forest model for class ...

  4. Spark随机深林扩展—OOB错误评估和变量权重

    本文目的 当前spark(1.3版)随机森林实现,没有包括OOB错误评估和变量权重计算.而这两个功能在实际工作中比较常用.OOB错误评估可以代替交叉检验,评估模型整体结果,避免交叉检验带来的计算开销. ...

  5. Spark2.0机器学习系列之6:GBDT(梯度提升决策树)、GBDT与随机森林差异、参数调试及Scikit代码分析

    概念梳理 GBDT的别称 GBDT(Gradient Boost Decision Tree),梯度提升决策树.     GBDT这个算法还有一些其他的名字,比如说MART(Multiple Addi ...

  6. 机器学习第5周--炼数成金-----决策树,组合提升算法,bagging和adaboost,随机森林。

    决策树decision tree 什么是决策树输入:学习集输出:分类觃则(决策树) 决策树算法概述 70年代后期至80年代初期,Quinlan开发了ID3算法(迭代的二分器)Quinlan改迚了ID3 ...

  7. 04-10 Bagging和随机森林

    目录 Bagging算法和随机森林 一.Bagging算法和随机森林学习目标 二.Bagging算法原理回顾 三.Bagging算法流程 3.1 输入 3.2 输出 3.3 流程 四.随机森林详解 4 ...

  8. 100天搞定机器学习|Day56 随机森林工作原理及调参实战(信用卡欺诈预测)

    本文是对100天搞定机器学习|Day33-34 随机森林的补充 前文对随机森林的概念.工作原理.使用方法做了简单介绍,并提供了分类和回归的实例. 本期我们重点讲一下: 1.集成学习.Bagging和随 ...

  9. 第七章——集成学习和随机森林(Ensemble Learning and Random Forests)

    俗话说,三个臭皮匠顶个诸葛亮.类似的,如果集成一系列分类器的预测结果,也将会得到由于单个预测期的预测结果.一组预测期称为一个集合(ensemble),因此这一技术被称为集成学习(Ensemble Le ...

随机推荐

  1. 再见Unity3d的死循环

    前两天看见http://www.manew.com/thread-89909-1-1.html这篇译文之前几个小时刚好解决了一个莫名的死循环问题,然后忍不住要把另外一种方法告诉蛮友们.这个方法不需要知 ...

  2. EditText 焦点

    让EditText不自动获取焦点,只需要在EditText的父控件加上 android:focusable="true"android:focusableInTouchMode=& ...

  3. chmod和fchmod函数 /chown ,fchown,lchown函数

    这两个函数使我们可以更改现有文件的访问权限: #include <sys/stat.h> int chmod( const char *pathname, mode_t mode ); i ...

  4. 如何解决PC端和移动端自适应问题?

    做网页时,我们通常需要考虑到不同电脑屏幕尺寸,以及不同手机屏幕大小等问题,解决样式发生改变的情况,那么如何解决呢?现在主要是采用自适应来解决高度,宽度的,以及图片自适应问题,下面就PC端和移动端来总结 ...

  5. Swift经典知识整理

    1  关于Swift Swift 是一种适用于 iOS 和 OS X 应用的全新编程语言,它建立在最好的 C 和 Objective-C 语言之上,并且没有 C 语言的兼容性限制.Swift 采用安全 ...

  6. Python 输出文字带颜色

    格式:\033[显示方式;前景色;背景色m 说明:前景色            背景色           颜色---------------------------------------30    ...

  7. Xperf Basics: Recording a Trace (the easy way)(转)

      http://randomascii.wordpress.com/2013/04/20/xperf-basics-recording-a-trace-the-easy-way/   Some ti ...

  8. memcached(二)事件模型源码分析

    memcachedd事件模型 在memcachedd中,作者为了专注于缓存的设计,使用了libevent来开发事件模型.memcachedd的时间模型同nginx的类似,拥有一个主进行(master) ...

  9. 配置SharePoint 2013 Search 拓扑结构

    在单台服务器上安装了 SharePoint Server 2013,并且创建了具有默认搜索拓扑的 Search Service 应用程序.在默认搜索拓扑中,所有搜索组件都位于承载管理中心的服务器上.S ...

  10. 微软今日发布汇总:VS2015, .NET 4.6, C# 6.0, F# 4.0等重量级产品正式上线

    Visual Studio Visual Studio 2015 下载 VS2015新功能列表 ‘ Visual Studio 2013 更新包 5.0 下载 其中包含Visual Studio 20 ...