在递归地构建关于spark的决策树时,我是否需要保存中间数据子集?

时间:2015-07-28 04:39:46

标签: scala recursion machine-learning apache-spark decision-tree

我正在Scala / Spark上构建决策树(在50节点集群上)。由于我的数据集有点大(~2TB),我想将它并行化。 我的代码看起来像这样

def buildTree(data: RDD[Array[Double]], numInstances: Int): Node = {

    // Base case
    if (numInstances < minInstances) {
        return new Node(isLeaf = true)
    }

    /*
    * Find best split for all columns in data
    */

    val leftRDD = data.filter(leftSplitCriteria)
    val rightRDD = data.filter(rightSplitCriteria)
    val subset = Seq(leftRDD, rightRDD)
    val counts = Seq(numLeft, numRight)

    val children = (0 until 2).map(i =>
                    (i,subset(i),counts(i)))
                    .par.map(x => {buildTree(x._2,x._3)})

    return new Node(children(0), children(1), Split)
}

我的问题是

  1. Scala是一种懒惰语言,不会立即计算map / filter操作的输出。因此,在构建新的Node时,父母的所有过滤器和父母的父母都会被堆叠(并递归应用)吗?
  2. 并行构建树的最佳方法是什么?我应该在中间步骤中缓存/保存数据集吗?
  3. 在运行此代码时,仅提供 num-executers 就足够了,或者如果我提供 executor-cores 驱动程序 - 它会有所作为核心等?

2 个答案:

答案 0 :(得分:1)

  1. 我假设numLeft是使用leftRDD.count()计算的,count是一个动作,会强制计算所有相关的RDD。

  2. 在这种情况下,您实际上会进行多次过滤,一次是计数,另一次是每个孩子依赖。你应该缓存你的RDD以避免重复计算,你只需要最后一个,这样你就可以在每个阶段unpersist前一个。{/ p>

  3. 有关详细说明,请参阅Apache Spark Method returning an RDD (with Tail Recursion)

    旁注:Spark使用了懒惰的评估模型,我想我们并不是说scala是一种懒惰的语言。

答案 1 :(得分:0)

我最终通过功能将每个级别的分裂发现并行化。

参考