我在一个50节点的集群上使用Scala/Spark构建决策树。由于我的数据集相当大(约2TB),我想对其进行并行处理。我的代码如下所示
def buildTree(data: RDD[Array[Double]], numInstances: Int): Node = { // 基本情况
if (numInstances < minInstances) {
return new Node(isLeaf = true)
}
/*
* 为数据中的所有列找到最佳分割
*/
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)}
我的问题是
- Scala作为一种惰性语言,不会立即计算map/filter操作的输出。因此,在构建新节点时,父节点以及父节点的父节点的所有过滤器是否会堆积起来(并递归应用)?
- 构建树的最佳并行方法是什么?我是否应该在中间步骤缓存/保存数据集?
- 运行此代码时,仅提供num-executers是否足够,或者如果我提供executor-cores、driver-cores等会有所不同?
回答:
我最终通过特征在每个层级并行化了分割查找过程。
参考