SparkML-从CrossValidator中的bestModel中检索参数

时间:2018-09-21 16:09:16

标签: scala apache-spark apache-spark-mllib

我正在使用StringIndexer,OneHotEncoderEstimator和RandomForestRegressor在Spark 2.3中训练随机森林模型。像这样:

//Indexer
val stringIndexers = categoricalColumns.map { colName =>
  new StringIndexer()
    .setInputCol(colName)
    .setOutputCol(colName + "Idx")
    .setHandleInvalid("keep")
    .fit(training)
}

//HotEncoder
val encoders = featuresEnconding.map { colName =>
  new OneHotEncoderEstimator()
    .setInputCols(Array(colName + "Idx"))
    .setOutputCols(Array(colName + "Enc"))
    .setHandleInvalid("keep")
}  

//Adding features into a feature vector column   
val assembler = new VectorAssembler()
              .setInputCols(featureColumns)
              .setOutputCol("features")


val rf = new RandomForestRegressor()
              .setLabelCol("label")
              .setFeaturesCol("features")
              .setMaxBins(1000)


val stepsRF = stringIndexers ++ encoders ++ Array(assembler, rf)

val pipelineRF = new Pipeline().setStages(stepsRF)

val paramGridRF = new ParamGridBuilder()
                  .addGrid(rf.minInstancesPerNode, Array(1, 5, 15))
                  .addGrid(rf.maxDepth, Array(10, 11, 12))
                  .addGrid(rf.numTrees, Array(20, 50, 100))
                  .build()


//Defining the evaluator
val evaluatorRF = new RegressionEvaluator()
.setLabelCol("label")
.setPredictionCol("prediction")

//Using cross validation to train the model
val cvRF = new CrossValidator()
.setEstimator(pipelineRF)
.setEvaluator(evaluatorRF)
.setEstimatorParamMaps(paramGridRF)
.setNumFolds(10)
.setParallelism(3)

//Fitting the model with our training dataset
val cvRFModel = cvRF.fit(training)

我不确定此模型的最佳参数组合是什么,因此我添加了以下参数网格:

.addGrid(rf.minInstancesPerNode, Array(1, 5, 15))
.addGrid(rf.maxDepth, Array(10, 11, 12))
.addGrid(rf.numTrees, Array(20, 50, 100))

然后我让CrossValidator计算出最佳组合。现在,我想找出它选择了哪种组合,以从那里继续调整模型。所以我试图像这样获取此参数:

cvRFModel.bestModel.extractParamMap

但是我得到的是空地图:

org.apache.spark.ml.param.ParamMap =
{

}

我想念什么?

1 个答案:

答案 0 :(得分:0)

基于以下question,我尝试了此操作,但是我不确定这是否正确:

val avgMetricsParamGrid = cvRFModel.avgMetrics

val combined = paramGridRF.zip(avgMetricsParamGrid)

val bestModel = cvRFModel.bestModel.asInstanceOf[PipelineModel]


val parms = bestModel.stages.last.asInstanceOf[RandomForestRegressionModel].explainParams

它给了我几个参数的信息:

  

labelCol:标签列名称(默认:标签,当前:标签)maxBins:   用于离散化连续特征的最大箱数。必须大于等于2   和> =任何分类特征的分类数。 (默认值:32,   当前:1000)maxDepth:树的最大深度。 (> = 0)例如,深度   0表示1个叶节点;深度1表示1个内部节点+ 2个叶节点。   (默认值:5,当前值:12)maxMemoryInMB:以MB为单位的最大内存   分配给直方图聚合。 (预设值:256)minInfoGain:   在树节点上考虑的拆分的最小信息增益。   (默认值:0.0)minInstancesPerNode:每个实例的最小数量   拆分后孩子必须有。如果分裂导致左或右   子节点少于minInstancesPerNode,则拆分为   视为无效而丢弃。应该> =1。(默认值:1,当前值:1)   numTrees:要训练的树数(> = 1)(默认值:20,当前值:20)   projectionCol:预测列名称(默认值:预测)种子:   随机种子(默认值:235498149)二次采样率:的分数   用于学习每个决策树的训练数据,范围为(0,1]。   (默认:1.0)

我不确定还是需要选择哪个阶段。由于培训过程是反复进行的,因此我决定选择最后一个,但是我不确定100%是否是正确的答案。任何反馈将不胜感激。