在 spark 上递归构建决策树时,是否需要保存中间数据子集?
Do I need to I save intermediate subsets of data while building decision tree on spark recursively?
我正在 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)
}
我的问题是
- Scala 是一种惰性语言,不会立即计算 map/filter 操作的输出。那么在构建一个新节点时,是否将父节点的所有过滤器以及父节点的父节点堆叠起来(并递归应用)?
- 并行构建树的最佳方法是什么?我应该 cache/save 中间步骤中的数据集吗?
- 虽然 运行 这段代码,仅提供 num-executors 是否足够,或者如果我提供 executor- 是否会有所不同?核心数、驱动核心数等?
我假设 numLeft
是使用 leftRDD.count()
计算的,计数是一个动作,将强制计算所有依赖的 RDD。
在这种情况下,您实际上会进行不止一次过滤,一次用于计数,另一次用于每个子项依赖。你应该缓存你的 RDD 以避免重复计算,你只需要最后一个,这样你就可以在每个阶段 unpersist
前一个。
有关更多说明,请参阅
旁注:Spark 使用惰性求值模型,我认为我们不会说 scala 是一种惰性语言。
我最终按特征在每个级别并行化拆分查找。
参考
我正在 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)
}
我的问题是
- Scala 是一种惰性语言,不会立即计算 map/filter 操作的输出。那么在构建一个新节点时,是否将父节点的所有过滤器以及父节点的父节点堆叠起来(并递归应用)?
- 并行构建树的最佳方法是什么?我应该 cache/save 中间步骤中的数据集吗?
- 虽然 运行 这段代码,仅提供 num-executors 是否足够,或者如果我提供 executor- 是否会有所不同?核心数、驱动核心数等?
我假设
numLeft
是使用leftRDD.count()
计算的,计数是一个动作,将强制计算所有依赖的 RDD。在这种情况下,您实际上会进行不止一次过滤,一次用于计数,另一次用于每个子项依赖。你应该缓存你的 RDD 以避免重复计算,你只需要最后一个,这样你就可以在每个阶段
unpersist
前一个。
有关更多说明,请参阅
旁注:Spark 使用惰性求值模型,我认为我们不会说 scala 是一种惰性语言。
我最终按特征在每个级别并行化拆分查找。
参考