web-dev-qa-db-fra.com

Comment extraire les meilleurs paramètres d'un CrossValidatorModel

Je veux trouver les paramètres de ParamGridBuilder qui font le meilleur modèle dans CrossValidator dans Spark 1.4.x,

Dans Exemple de pipeline dans la documentation Spark, ils ajoutent différents paramètres (numFeatures, regParam) en utilisant ParamGridBuilder dans le pipeline. Ensuite, à la ligne de code suivante, ils créent le meilleur modèle:

val cvModel = crossval.fit(training.toDF)

Maintenant, je veux savoir quels sont les paramètres (numFeatures, regParam) de ParamGridBuilder qui produisent le meilleur modèle.

J'ai déjà utilisé les commandes suivantes sans succès:

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

De l'aide?

Merci d'avance,

23
Mohammad

Une méthode pour obtenir un objet ParamMap correct consiste à utiliser CrossValidatorModel.avgMetrics: Array[Double] pour rechercher le paramètre argmax ParamMap:

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

Lorsque vous utilisez la CrossValidatorModel formée dans le pipeline, vous avez cité l'exemple suivant:

scala> println(cvModel.bestEstimatorParamMap)
{
   hashingTF_2b0b8ccaeeec-numFeatures: 100,
   logreg_950a13184247-regParam: 0.1
}
15
Adam Vogel
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)

la source

12
macfeliga

Voici comment vous obtenez les paramètres choisis

println(cvModel.bestModel.getMaxIter)   
println(cvModel.bestModel.getRegParam)  
3
Mazen Aly

ce code Java devrait fonctionner: cvModel.bestModel().parent().extractParamMap().vous pouvez le traduire en code scala parent()method renverra un estimateur, vous pourrez alors obtenir les meilleurs paramètres.

2
orangeHIX

C'est la ParamGridBuilder () 

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

Il y a 3 étapes dans le pipeline. Il semble que nous puissions évaluer les paramètres comme suit:

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
[]

Cependant, il n'y a pas de paramètre dans la dernière étape, logiscRegression.

Nous pouvons également obtenir les paramètres poids et interception de la régression logistique comme suit:

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])

Exploration complète: http://kuanliang.github.io/2016-06-07-SparkML-pipeline/

1
劉冠良

Je travaille avec Spark Scala 1.6.x et voici un exemple complet de la façon dont je peux définir et adapter une CrossValidator, puis renvoyer la valeur du paramètre utilisé pour obtenir le meilleur modèle (en supposant que training.toDF donne un cadre de données prêt à être utilisé) :

import org.Apache.spark.ml.classification.LogisticRegression
import org.Apache.spark.ml.tuning.{CrossValidator, ParamGridBuilder}
import org.Apache.spark.ml.evaluation.MulticlassClassificationEvaluator

// Instantiate a LogisticRegression object
val lr = new LogisticRegression()

// Instantiate a ParamGrid with different values for the 'RegParam' parameter of the logistic regression
val paramGrid = new ParamGridBuilder().addGrid(lr.regParam, Array(0.0001, 0.001, 0.01, 0.1, 0.25, 0.5, 0.75, 1)).build()

// Setting and fitting the CrossValidator on the training set, using 'MultiClassClassificationEvaluator' as evaluator
val crossVal = new CrossValidator().setEstimator(lr).setEvaluator(new MulticlassClassificationEvaluator).setEstimatorParamMaps(paramGrid)
val cvModel = crossVal.fit(training.toDF)

// Getting the value of the 'RegParam' used to get the best model
val bestModel = cvModel.bestModel                    // Getting the best model
val paramReference = bestModel.getParam("regParam")  // Getting the reference of the parameter you want (only the reference, not the value)
val paramValue = bestModel.get(paramReference)       // Getting the value of this parameter
print(paramValue)                                    // In my case : 0.001

Vous pouvez faire la même chose pour n’importe quel paramètre ou tout autre type de modèle.

0
François

 enter image description here

Si Java, voyez cette émission de débogage;

bestModel.parent().extractParamMap()
0
裴帅帅

Pour tout imprimer dans paramMap, vous n'avez pas besoin d'appeler le parent:

cvModel.bestModel().extractParamMap()

Pour répondre à la question de OP, pour obtenir un seul meilleur paramètre, par exemple regParam:

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