mahout的并行随机森林是怎样创建的

我挺好奇mahout是怎样分布式建立一个随机森林的,所以特意看看它的BuildForest源码,看看里边的mapreduce是怎样实现的。

还有个问题也挺让我好奇的,就是随机森林是怎么保存的呢?

我看的是0.9版本的mahout。

首先想想随机森林的可并行性在哪里?如果是我来做并行,会怎么做呢?

因为随机森林是由很多决策树组成,而这些决策树建立的时候相互之间是不影响的,所以建树这个过程便是可以并行化的。

接着考虑数据问题,以前我用weka编程,一个1G多的数据全部用来做训练,然后就会报内存溢出,所以在大数据下,这个问题该怎么解决呢?

数据太大,一般都会切分成很多block,放在不同的datanode里边存储,那么是要把所有数据都拿到然后训练还是该怎么做呢?

看看mahout是怎么解决这个问题的吧!

BuildForest类

首先从BuildForest类开始,这个类在package org.apache.mahout.classifier.df.mapreduce里边,

在mahout-distribution-0.9\examples\src\main\java\org\apache\mahout\classifier\df\mapreduce文件夹里边。

这个类定义的参数如下,依次为:

  1. dataPath,数据集路径
  2. datasetPath,虽然名为数据集,但实际上是描述数据集的文件,也即描述数据各个属性以及label属性
  3. outputPath,生成的随机森林的保存路径
  4. m,生成决策树的时候每次随机选择的参数个数
  5. complemented,生成的树是否为完全树么
  6. minSplitNum,分类树判断一个节点是否需要继续分裂下去时使用,如果一个节点里边属性数目小于minSplitNum,那么就不再分裂,设置为叶子节点
  7. minVarianceProportion,同上,不过是回归树使用
  8. nbTrees,森林的决策树数目
  9. seed,随机种子
  10. isPartial,我觉得这个挺有意思的,使用部分数据,怎么选择部分呢?剩下的部分呢?

  private Path dataPath;
  
  private Path datasetPath;

  private Path outputPath;

  private Integer m; // Number of variables to select at each tree-node

  private boolean complemented; // tree is complemented
  
  private Integer minSplitNum; // minimum number for split

  private Double minVarianceProportion; // minimum proportion of the total variance for split

  private int nbTrees; // Number of trees to grow
  
  private Long seed; // Random seed
  
  private boolean isPartial; // use partial data implementation


这个类继续Configured类实现Tool接口,所以需要重载run方法。

run方法首先处理输入参数,这一段不是我关注的,所以不管它啦,

读取参数之后,便运行了一个buildForest函数。


buildForest函数

首先判断输出目录是否存在,这个在运行hadoop程序的时候倒是经常遇见哦,输出文件存在就会报错的。
// make sure the output path does not exist
    FileSystem ofs = outputPath.getFileSystem(getConf());
    if (ofs.exists(outputPath)) {
      log.error("Output path already exists");
      return;
    }

然后是决策树生成器的创建,并根据输入设置它的参数。
DecisionTreeBuilder treeBuilder = new DecisionTreeBuilder();
    if (m != null) {
      treeBuilder.setM(m);
    }
    treeBuilder.setComplemented(complemented);
    if (minSplitNum != null) {
      treeBuilder.setMinSplitNum(minSplitNum);
    }
    if (minVarianceProportion != null) {
      treeBuilder.setMinVarianceProportion(minVarianceProportion);
    }

接着是森林生成器的创建,依然是根据输入设置参数。
Builder forestBuilder;
    
    if (isPartial) {
      log.info("Partial Mapred implementation");
      forestBuilder = new PartialBuilder(treeBuilder, dataPath, datasetPath, seed, getConf());
    } else {
      log.info("InMem Mapred implementation");
      forestBuilder = new InMemBuilder(treeBuilder, dataPath, datasetPath, seed, getConf());
    }

    forestBuilder.setOutputDirName(outputPath.getName());

最后就是生成森林以及保存森林了。
DecisionForest forest = forestBuilder.build(nbTrees);

// store the decision forest in the output path
    Path forestPath = new Path(outputPath, "forest.seq");
    log.info("Storing the forest in: {}", forestPath);
    DFUtils.storeWritable(getConf(), forestPath, forest);

forestBuild

创建森林的方式有两种,它考虑了数据的问题,所以给出inMem和partial两种方式,简而言之,就是
  1. 数据不大的话,把所有数据都放到内存中,然后用所有数据训练决策树
  2. 数据很大的话,把Mapper所在节点的这部分数据取出来用作训练,其它数据不管
那先来看看Builder这个基类。

Builder

Builder类需要关注的几个函数:

setTreeBuilder和getTreeBuilder

Configuration保存变量的方式是以conf.set("name", value)形式保存,
取得变量则是以conf.get("name")方式,和JavaWeb里边的session好像哦。

StringUtils真是很神奇啊!!居然可以把TreeBuilder当做
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值