6

ich eine Pipeline mit einer DecisionTreeClassifier (dt) gebaut wie diesewie das trainierte beste Modell von einem crossvalidator erhalten

val pipeline = new Pipeline().setStages(Array(labelIndexer, featureIndexer, dt, labelConverter)) 

Dann habe ich diese Pipeline als Schätzer in einem CrossValidator, um ein Modell mit bekommen der beste Satz von Hyper wie diese

val c_v = new CrossValidator().setEstimator(pipeline).setEvaluator(new MulticlassClassificationEvaluator().setLabelCol("indexedLabel").setPredictionCol("prediction")).setEstimatorParamMaps(paramGrid).setNumFolds(5) 

Schließlich könnte ich ein Modell auf einem Trainingstest mit diesem crossvalidator

val model = c_v.fit(train) 
trainieren

Aber die Frage ist, ich möchte das am besten ausgebildete Entscheidungsbaummodell mit dem Parameter .toDebugTree von DecisionTreeClassificationModel anzeigen. Aber Modell ist ein CrossValidatorModel. Ja, Sie können model.bestModel verwenden, aber es ist immer noch vom Typ Model, Sie können .toDebugTree nicht darauf anwenden. Und ich nehme auch an, dass das beste Modell immer noch eine Pipline ist, einschließlich labelIndexer, featureIndexer, dt, labelConverter.

Also weiß jemand, wie ich das DecisionTree Modell von dem Modell erhalten kann, das durch die crossvalidator gepasst wird, die ich das tatsächliche Modell durch toDebugString sehen konnte? Oder gibt es eine Problemumgehung, die ich das DecisionTree-Modell anzeigen kann?

Antwort

8

Nun, in cases like this one ist die Antwort immer die gleiche - seien Sie spezifisch über die Typen.

zuerst das Pipeline-Modell extrahieren, da das, was Sie versuchen, eine Pipeline zu trainieren:

import org.apache.spark.ml.PipelineModel 

val bestModel: Option[PipelineModel] = model.bestModel match { 
    case p: PipelineModel => Some(p) 
    case _ => None 
} 

Dann müssen Sie das Modell aus der darunter liegenden Stufe extrahieren. In Ihrem Fall ist es ein Entscheidungsbaum Klassifikationsmodell:

import org.apache.spark.ml.classification.DecisionTreeClassificationModel 

val treeModel: Option[DecisionTreeClassificationModel] = bestModel 
    flatMap { 
    _.stages.collect { 
     case t: DecisionTreeClassificationModel => t 
    }.headOption 
    } 

Um den Baum, zum Beispiel zu drucken:

treeModel.foreach(_.toDebugString) 
+0

Danke Mann! Genau danach suche ich. –

+0

Gern geschehen, und wenn dies eine Lösung ist, die Sie gesucht haben, akzeptieren Sie bitte die Antwort. – zero323

+0

Danke, versuchte es hier auf einem LinearRegressionModel https://databricks-prod-cloudfront.cloud.databricks.com/public/4027ec902e239c93eaaa8714f173bcfc/1221303294178191/2620145786109408/6190062569763605/latest.html – oluies

3

(HAFTUNGSAUSSCHLUSS:. Es gibt einen weiteren Aspekt, der imho seine eigene Antwort verdient Ich weiß es jedoch ist ein wenig die Frage gegeben OT, in Frage stellt, ist es die Frage. Wenn jemand nach unten Stimmen, weil er mit dem Inhalt nicht einverstanden bitte auch einen Kommentar hinterlassen)

Sollten Sie den „besten“ Baum extrahieren und die Antwort ist in der Regel nicht.

Warum machen wir CV? Wir versuchen, unsere Entscheidungen zu bewerten, zu bekommen. Die Auswahlmöglichkeiten sind die verwendeten Klassifizierer, die verwendeten Hyperparameter, die Vorverarbeitung wie die Merkmalsauswahl. Für den letzten ist es wichtig, dass dies auf den Trainingsdaten geschieht. Z. B. normalisieren Sie nicht die Merkmale aller Daten. Die Ausgabe von CV ist also die erzeugte Pipeline. Nebenbei bemerkt: die Feature-Auswahl sollte auf einem "internen cv"

ausgewertet werden. Was wir nicht tun, erzeugen wir keinen "Pool von Klassifikatoren", wo wir den besten Klassifikator wählen. Allerdings habe ich das überraschend oft gesehen. Das Problem ist, dass Sie eine extrem hohe Chance auf einen Twining-Effekt haben. Selbst in einem perfekten I ID-Datensatz gibt es wahrscheinlich (fast) doppelte Trainingsbeispiele. Es gibt eine ziemlich gute Chance, dass der "beste" CV-Klassifikator nur ein Hinweis darauf ist, in welcher Falte Sie die beste Verbindung haben.

Also, was sollten Sie tun?Sobald Sie Ihre Parameter festgelegt haben, sollten Sie die gesamten Trainingsdaten verwenden, um das endgültige Modell zu erstellen. Hoffentlich, aber niemand tut das, Sie haben einen zusätzlichen Bewertungssatz beiseite gelegt, den Sie in diesem Prozess nie berührt haben, um eine Bewertung Ihres endgültigen Modells zu erhalten.

+0

Sie auf jeden Fall einen Punkt, obwohl ich glaube, diese mehr ein Problem mit einem API-Design, das alles andere. Es gibt 'TrainValidationSplit (Model)', das hier sein könnte, obwohl ich mir nicht sicher bin, ob es eine gute Möglichkeit gibt, diese in einer einzigen 'Pipeline' zu kombinieren. – zero323

+1

Ja, ich stimme völlig zu, was Sie sagen. Der Grund, warum ich das beste Modell sehen möchte, ist nur aus Neugierde. –

Verwandte Themen