2016-04-12 8 views
2

Ich benutze Scala und verwende StringIndexer, um Indizes zu jeder Kategorie in meinem Trainingssatz zuzuweisen. Es ordnet Indizes basierend auf der Häufigkeit jeder Kategorie zu.Spark ML StringIndexer Verschiedene Etiketten Training/Testing

Das Problem ist, dass in meinen Testdaten die Häufigkeit der Kategorien unterschiedlich ist und so StringIndexer den Kategorien unterschiedliche Indizes zuweist, was mich daran hindert, das Modell (Random Forest) richtig zu bewerten.

Ich verarbeite die Trainings-/Testdaten genau auf die gleiche Weise und speichere das Modell nicht.

Ich habe manuell Erstellen von Etiketten versucht (durch den Index der Kategorie bekommen), aber bekommen diesen Fehler

java.lang.IllegalArgumentException: RandomForestClassifier was given input with invalid label column label, without the number of classes specified. See StringIndexer. 

Es scheint, dass ich StringIndexer verwenden müssen, so wie stelle ich sicher, dass zukünftige Datensätze, die ich benutze zum Testen die Kategorien auf die gleiche Weise wie das Trainingsprogramm indexieren?

EDIT Hinzufügen von Code meiner versucht Abhilfe

Dies ist, was die Datenrahmen aussieht, nennen es mydata

+--------+-----+---------+---------+ 
|category|label|  x|  y| 
+--------+-----+---------+---------+ 
| a|  0.0| -0.166992|-0.256348| 
| b|  1.0| -0.179199| -0.22998| 
| c|  2.0| -0.172119|-0.105713| 
| d|  3.0| -0.064209| 0.050293| 

I-Vektor-Assembler verwenden Funktionen zur Vorbereitung

val assembler = new VectorAssembler().setInputCols(Array("x, y")).setOutputCol("features") 

Trans mydata verwendet über Assembler, der die Feature-Spalte

ausführt
val predValues = assembler.transform(mydata) 

Also das Modell erwartet 2 Spalten, Features und Label. Daher möchte ich ein eigenes Label dafür verwenden. ich wählen Features von predvalues ​​

val features = sqlContext.sql("SELECT features from predValues") 

und wählen Sie Etikett aus meiner df

val labelDF = sqlContext.sql("SELECT label FROM filterFeaturesOnly") 

Und dann die beiden zusammen kommen, damit ich Funktionen haben werden und Label zu modellieren passieren

val featuresAndLabels = features.join(labelDF) 

Dies ist, was ich an das Modell übergebe, und ich bekomme den oben genannten Fehler.

val label = predValues.join(labelDF) 
+1

Können Sie die Frage mit Ihrem Code aktualisieren. – Vishnu667

+0

@ Vishnu667 Ich habe die Frage aktualisiert. – other15

Antwort

7

Wenn Sie wollen die Dinge konsequent beschriften, dann müssen Sie den Einbau stringIndexer speichern.

Betrachten this sample code aus der Dokumentation:

val indexer = new StringIndexer() 
    .setInputCol("category") 
    .setOutputCol("categoryIndex") 

val indexed = indexer.fit(df).transform(df) 

Das indexer.fit(df) Stück eine StringIndexerModel zurückgibt, die dann die transform Funktion ausführen können. Also statt:

val indexerModel = indexer.fit(trainDF) 
val indexed = indexerModel.transform(trainDF) 

die später können Sie indexerModel.transform(testDF) verwenden, um die gleichen Bezeichnungen für die gleichen Eingänge zu erhalten.

+1

Das hat funktioniert! Genau das, was ich gesucht habe, danke Matthew (Habe nicht genug Punkte, um deine Antwort zu verbessern) – other15

Verwandte Themen