我在群集上执行Spark作业。虽然它在本地模式下运行完美,但在集群中它在以下行中失败:
val labelsAndPredictions = testData.map(p => (model.predict(p.features), p.label))
我理解这个问题可能与工作人员无法访问对象model
这一事实有关。因此我尝试了另一种方法。我创建了一个带有两个函数的可序列化对象Utils
:
object Utils {
var model: GradientBoostedTreesModel = null
def loadModel(m: GradientBoostedTreesModel): Unit = {
model = m
}
def makePrediction(features: org.apache.spark.mllib.linalg.Vector): Double = {
println(model.trees)
val predictedLabel = model.predict(features)
println("predictedLabel: " + predictedLabel)
predictedLabel
}
}
然后我将预测替换如下:
model = GradientBoostedTrees.train(trainingData, boostingStrategy)
Utils.loadModel(model)
val labelsAndPredictions = testData.map { x =>
val prediction = Utils.makePrediction(x.features)
(x.label, prediction)
}
这是我用来提交Spark作业的命令:
spark-submit --master yarn --deploy-mode cluster --driver-memory 10g --executor-memory 10g --num-executors 2 --conf "spark.executor.extraJavaOptions=-XX:+UseG1GC -XX:+AlwaysPreTouch" --class org.test.Runner s3://mybucket/keys/trainer.jar
答案 0 :(得分:0)
utils对象无法解决问题,因为模型初始化为驱动程序而非工作者。
我最后一次检查(1.6.x)模型确实不可序列化。
你能做的是:
model.predict(testData.map(_.features))
但是这不会为你提供一个很好的方法来评估没有标签的模型。
或者
testData.toLocalIterator.map { x => (x.label, model.predict(x.features)) }
toLocalIterator迭代每个分区中的数据,但是在驱动程序而不是工作程序上,使您可以访问模型。不幸的是,没有并行化。