14

voglio trovare i parametri di ParamGridBuilder che rendono il miglior modello in CrossValidator in Spark 1.4.x,Come estrarre migliori parametri da un CrossValidatorModel

In Pipeline Example nella documentazione Spark, aggiungono diversi parametri (numFeatures, regParam) utilizzando ParamGridBuilder nella pipeline. Poi dalla seguente riga di codice che fanno il miglior modello:

val cvModel = crossval.fit(training.toDF) 

Ora, voglio sapere quali sono i parametri (numFeatures, regParam) da ParamGridBuilder che produce il modello migliore.

ho già usato i seguenti comandi senza successo:

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

Qualsiasi aiuto?

Grazie in anticipo,

+2

I migliori parametri sono [inviati per il log] (https://github.com/apache/spark/blob/a721ee52705100dbd7852f80f92cde4375517e48/mllib/src/main/scala/org/apache/spark/ml/tuning/CrossValidator.scala# L104) ma mi batte come è possibile accedere a queste informazioni da un'istanza di 'CrossValidatorModel'. – zero323

+1

Questo è davvero frustrante. Non lo stanno nemmeno loggando in PySpark. Una cosa così piccola ma importante che manca ... mi chiedo se qualcuno stia effettivamente utilizzando questa funzionalità. –

+0

persone, qualsiasi soluzione per questo problema nelle versioni recenti di Spark? – Rami

risposta

9
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

12

Un metodo per ottenere una corretta ParamMap oggetto è quello di utilizzare CrossValidatorModel.avgMetrics: Array[Double] per trovare l'argmax ParamMap:

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

Quando viene eseguito sul CrossValidatorModel addestrato nell'esempio della pipeline che hai citato dà:

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

Nota: 'maxBy' potrebbe essere necessario' minBy', a seconda del valore di 'Evaluator.isLargerBetter'. – metasim

1

Questa è la ParamGridBuilder()

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

Ci sono 3 tappe in pipeline. Sembra che siamo in grado di valutare i parametri come il seguente:

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

Tuttavia, non esiste un parametro nell'ultima fase, logiscRegression.

Possiamo anche ottenere peso e intercetta parametro dal logistregression come la seguente:

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

esplorazione completa: http://kuanliang.github.io/2016-06-07-SparkML-pipeline/

3

Ecco come ottenere i parametri scelti

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

Si prega di non aggiungere la stessa risposta a più domande. Rispondi al migliore e contrassegna il resto come duplicato. Vedi http://meta.stackexchange.com/questions/104227/is-it-acceptable-to-add-a-duplicate-answer-to-several-questions –

1

questo codice Java dovrebbe funzionare: cvModel.bestModel().parent().extractParamMap() .potete tradurre al codice Scala parent() metodo restituirà un estimatore, è possibile ottenere i migliori params poi.