Spark随机森林实现学习
前言
最近阅读了spark mllib(版本:spark 1.3)中Random Forest的实现,发现在分布式的数据结构上实现迭代算法时,有些地方与单机环境不一样。单机上一些直观的操作(递归),在分布式数据上,必须进行优化,否则I/O(网络,磁盘)会消耗大量时间。本文整理spark随机森林实现中的相关技巧,方便后面回顾。
随机森林算法概要
随机森林算法的详细实现和细节,可以参考论文Breiman 2001。这里简单说说大体思路,方便理解代码。
随机森林是一个组装(ensemble model)模型,内部的模型使用决策树。基本思想是生成很多很多决策树(构成森林),最后由这些决策数一起投票决定最终结果。生成树的过程中,从行和列两个方向添加随机过程。行方向,在构建每棵树前,使用有放回抽样(称为Bootstrapping),得到训练数据。列方向,每次选择切分点时,对feature进行无放回随机抽样,得到一个feature子集,在当前节点上,只使用这些子集对应的数据计算最优切分点。这也是为什么此算法称为随机森林,是不是很直观。相比于单一决策树,随机森林有以下一些优点:
- 结果比较稳定,不容易出现过拟合;
- Out-Of-Bag error评估模型效果,无需交叉检验;
- 可得到feature重要性。
当然,为了得到上面的优点,必须付出计算开销作为代价。在单机时代,使用随机森林(R或scikit-learn)往往成本很高,但是现在有了spark,使得大规模,分布式迭代计算成为了可能,所以在spark上运用随机森林是技术发展的必然结果!
Spark实现优化
spark在实现随机森林时,采用了下面几个优化策略:
- 切分点抽样
- feature装箱(bin)
- 分区统计
- 逐层计算(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 随机森林建模数据量有质的飞跃,导致性能提升
参考资料
Spark随机森林实现学习的更多相关文章
- Spark随机森林实战
package big.data.analyse.ml.randomforest import org.apache.spark.ml.Pipeline import org.apache.spark ...
- spark 随机森林算法案例实战
随机森林算法 由多个决策树构成的森林,算法分类结果由这些决策树投票得到,决策树在生成的过程当中分别在行方向和列方向上添加随机过程,行方向上构建决策树时采用放回抽样(bootstraping)得到训练数 ...
- python spark 随机森林入门demo
class pyspark.mllib.tree.RandomForest[source] Learning algorithm for a random forest model for class ...
- Spark随机深林扩展—OOB错误评估和变量权重
本文目的 当前spark(1.3版)随机森林实现,没有包括OOB错误评估和变量权重计算.而这两个功能在实际工作中比较常用.OOB错误评估可以代替交叉检验,评估模型整体结果,避免交叉检验带来的计算开销. ...
- Spark2.0机器学习系列之6:GBDT(梯度提升决策树)、GBDT与随机森林差异、参数调试及Scikit代码分析
概念梳理 GBDT的别称 GBDT(Gradient Boost Decision Tree),梯度提升决策树. GBDT这个算法还有一些其他的名字,比如说MART(Multiple Addi ...
- 机器学习第5周--炼数成金-----决策树,组合提升算法,bagging和adaboost,随机森林。
决策树decision tree 什么是决策树输入:学习集输出:分类觃则(决策树) 决策树算法概述 70年代后期至80年代初期,Quinlan开发了ID3算法(迭代的二分器)Quinlan改迚了ID3 ...
- 04-10 Bagging和随机森林
目录 Bagging算法和随机森林 一.Bagging算法和随机森林学习目标 二.Bagging算法原理回顾 三.Bagging算法流程 3.1 输入 3.2 输出 3.3 流程 四.随机森林详解 4 ...
- 100天搞定机器学习|Day56 随机森林工作原理及调参实战(信用卡欺诈预测)
本文是对100天搞定机器学习|Day33-34 随机森林的补充 前文对随机森林的概念.工作原理.使用方法做了简单介绍,并提供了分类和回归的实例. 本期我们重点讲一下: 1.集成学习.Bagging和随 ...
- 第七章——集成学习和随机森林(Ensemble Learning and Random Forests)
俗话说,三个臭皮匠顶个诸葛亮.类似的,如果集成一系列分类器的预测结果,也将会得到由于单个预测期的预测结果.一组预测期称为一个集合(ensemble),因此这一技术被称为集成学习(Ensemble Le ...
随机推荐
- 打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数本身。例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方。
public class Three_03 { public static void main(String[] args) { for(int i=100;i<1000;i++){ int a ...
- NSLog函数重写
跟C++的输出函数相比,NSlog函数有个很大的优势,就是它可以输出对象. 在实际使用过程中,我们可以通过实现description函数来实现对NSLog函数的重写 -(NSString*)descr ...
- 必填项(required)
当你设计表单时,你可以指定某些选项为必填项(required),只有当用户填写了该选项后,用户才能够提交表单. 例如,如果你想把一个文本输入字段设置为必填项,在你的input元素中加上required ...
- linux-01Red Hat Enterprise Linux 7(RHEL7)配置静态IP地址
为方便在学习linux readhat7,在本地安装安装了虚拟机.为能够用win7连接虚拟机的linux远程客户端操作,则需要虚拟机和win本地的网络互通: 操作如下:1.本地配置ip地址 : 2.验 ...
- entlib验证组件
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- RaisingStudio.SessionFactory 发布 0.1版
功能描述: 1. 支持Orchard中方便使用自定义数据库连接. 2. 连接信息可配置. 用法: 1. 构造函数中添加IRepositoryFactory引用 private readonly IRe ...
- git ssh key创建和github使用
github拉代码需要ssh验证 git是分布式的代码管理工具,远程的代码管理是基于ssh的,所以要使用远程的git则需要ssh的配置. 一 .设置git: 设置git的user name和ema ...
- Dynamic CRM 2013学习笔记(十六)用JS控制Tab可见,可用
一个Form里经常会有好几个Tab,有时要根据一些条件设置哪些Tab可用,可见.下面就介绍下如何用JS对Tab进行控制. 1. 控制可见 function setTabVisableByName( ...
- Asp.Net Web API 2第十三课——ASP.NET Web API中的JSON和XML序列化
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文描述ASP.NET W ...
- 设计模式之美:Builder(生成器)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Builder 为每个构件定义一个操作. 实现方式(二):Builder 将构件返回给 Director,Director 将构 ...