如何从CrossValidatorModel

时间:2015-07-31 15:12:27

标签: scala apache-spark pipeline cross-validation apache-spark-mllib

我想在Spark 1.4.x中找到使用CrossValidator中最佳模型的ParamGridBuilder参数,

在Spark文档中的Pipeline Example中,他们使用管道中的numFeatures添加了不同的参数(regParamParamGridBuilder)。然后通过以下代码行创建最佳模型:

val cvModel = crossval.fit(training.toDF)

现在,我想知道numFeatures中产生最佳模型的参数(regParamParamGridBuilder)是什么。

我已经使用了以下命令但没有成功:

cvModel.bestModel.extractParamMap().toString()
cvModel.params.toList.mkString("(", ",", ")")
cvModel.estimatorParamMaps.toString()
cvModel.explainParams()
cvModel.getEstimatorParamMaps.mkString("(", ",", ")")
cvModel.toString()

任何帮助?

提前致谢,

11 个答案:

答案 0 :(得分:16)

获取正确的ParamMap对象的一种方法是使用CrossValidatorModel.avgMetrics: Array[Double]查找argmax ParamMap

implicit class BestParamMapCrossValidatorModel(cvModel: CrossValidatorModel) {
  def bestEstimatorParamMap: ParamMap = {
    cvModel.getEstimatorParamMaps
           .zip(cvModel.avgMetrics)
           .maxBy(_._2)
           ._1
  }
}

在管道示例中训练的CrossValidatorModel上运行时,您引用了:

scala> println(cvModel.bestEstimatorParamMap)
{
   hashingTF_2b0b8ccaeeec-numFeatures: 100,
   logreg_950a13184247-regParam: 0.1
}

答案 1 :(得分:12)

val bestPipelineModel = cvModel.bestModel.asInstanceOf[PipelineModel]
val stages = bestPipelineModel.stages

val hashingStage = stages(1).asInstanceOf[HashingTF]
println("numFeatures = " + hashingStage.getNumFeatures)

val lrStage = stages(2).asInstanceOf[LogisticRegressionModel]
println("regParam = " + lrStage.getRegParam)

source

答案 2 :(得分:3)

这是您获取所选参数的方式

println(cvModel.bestModel.getMaxIter)   
println(cvModel.bestModel.getRegParam)  

答案 3 :(得分:2)

这个java代码应该工作: parent()。您可以将其翻译为scala代码 tls:{ rejectUnauthorized:false } 方法会返回一个估算器,然后就可以得到最好的参数。

答案 4 :(得分:1)

这是ParamGridBuilder()

paraGrid = ParamGridBuilder().addGrid(
hashingTF.numFeatures, [10, 100, 1000]
).addGrid(
    lr.regParam, [0.1, 0.01, 0.001]
).build()

管道中有3个阶段。我们似乎可以按以下方式评估参数:

for stage in cv_model.bestModel.stages:
    print 'stages: {}'.format(stage)
    print stage.params
    print '\n'

stage: Tokenizer_46ffb9fac5968c6c152b
[Param(parent='Tokenizer_46ffb9fac5968c6c152b', name='inputCol', doc='input column name'), Param(parent='Tokenizer_46ffb9fac5968c6c152b', name='outputCol', doc='output column name')]

stage: HashingTF_40e1af3ba73764848d43
[Param(parent='HashingTF_40e1af3ba73764848d43', name='inputCol', doc='input column name'), Param(parent='HashingTF_40e1af3ba73764848d43', name='numFeatures', doc='number of features'), Param(parent='HashingTF_40e1af3ba73764848d43', name='outputCol', doc='output column name')]

stage: LogisticRegression_451b8c8dbef84ecab7a9
[]

但是,最后一个阶段没有参数logiscRegression。

我们还可以从logistregression获取 权重 拦截 参数,如下所示:

cv_model.bestModel.stages[1].getNumFeatures()
10
cv_model.bestModel.stages[2].intercept
1.5791827733883774
cv_model.bestModel.stages[2].weights
DenseVector([-2.5361, -0.9541, 0.4124, 4.2108, 4.4707, 4.9451, -0.3045, 5.4348, -0.1977, -1.8361])

全面探索: http://kuanliang.github.io/2016-06-07-SparkML-pipeline/

答案 5 :(得分:1)

要打印paramMap中的所有内容,您实际上不必致电父母:

cvModel.bestModel().extractParamMap()

要回答OP的问题,要获得一个最佳参数,例如regParam

cvModel.bestModel().extractParamMap().apply(cvModel.bestModel.getParam("regParam"))

答案 6 :(得分:0)

我正在使用Spark Scala 1.6.x,这是我如何设置和拟合CrossValidator然后返回用于获得最佳模型的参数值的完整示例(假设{{ 1}}提供了可以使用的数据框):

training.toDF

您可以对任何参数或任何其他类型的模型执行相同的操作。

答案 7 :(得分:0)

enter image description here

如果是Java,请参见此调试显示;

bestModel.parent().extractParamMap()

答案 8 :(得分:0)

在@macfeliga解决方案中构建,该解决方案适用于管道:

cvModel.bestModel.asInstanceOf[PipelineModel]
    .stages.foreach(stage => println(stage.extractParamMap))

答案 9 :(得分:0)

This SO thread可以回答这个问题。

总而言之,您需要将每个对象强制转换为它的假定类。

对于CrossValidatorModel,以下是我所做的:

import org.apache.spark.ml.tuning.CrossValidatorModel
import org.apache.spark.ml.PipelineModel
import org.apache.spark.ml.regression.RandomForestRegressionModel

// Load CV model from S3
val inputModelPath = "s3://path/to/my/random-forest-regression-cv"
val reloadedCvModel = CrossValidatorModel.load(inputModelPath)

// To get the parameters of the best model
(
    reloadedCvModel.bestModel
        .asInstanceOf[PipelineModel]
        .stages(1)
        .asInstanceOf[RandomForestRegressionModel]
        .extractParamMap()
)

在该示例中,我的管道有两个阶段(一个VectorIndexer和一个RandomForestRegressor),因此该模型的阶段索引为1。

答案 10 :(得分:0)

对于我来说,@ orangeHIX解决方案是完美的:

val cvModel = cv.fit(training)

val cvMejorModelo = cvModel.bestModel.asInstanceOf[ALSModel]

cvMejorModelo.parent.extractParamMap()

res86: org.apache.spark.ml.param.ParamMap =
{
    als_08eb64db650d-alpha: 0.05,
    als_08eb64db650d-checkpointInterval: 10,
    als_08eb64db650d-coldStartStrategy: drop,
    als_08eb64db650d-finalStorageLevel: MEMORY_AND_DISK,
    als_08eb64db650d-implicitPrefs: false,
    als_08eb64db650d-intermediateStorageLevel: MEMORY_AND_DISK,
    als_08eb64db650d-itemCol: product,
    als_08eb64db650d-maxIter: 10,
    als_08eb64db650d-nonnegative: false,
    als_08eb64db650d-numItemBlocks: 10,
    als_08eb64db650d-numUserBlocks: 10,
    als_08eb64db650d-predictionCol: prediction,
    als_08eb64db650d-rank: 1,
    als_08eb64db650d-ratingCol: rating,
    als_08eb64db650d-regParam: 0.1,
    als_08eb64db650d-seed: 1994790107,
    als_08eb64db650d-userCol: user
}