Contesto: Ho un frame di dati in cui tutti i valori categoriali sono stati indicizzati utilizzando StringIndexer.Applicazione di IndexToString al vettore di funzioni in Spark
val categoricalColumns = df.schema.collect { case StructField(name, StringType, nullable, meta) => name }
val categoryIndexers = categoricalColumns.map {
col => new StringIndexer().setInputCol(col).setOutputCol(s"${col}Indexed")
}
poi ho usato VectorAssembler vectorize tutte le colonne funzionalità (tra cui quelli categorici indicizzati).
val assembler = new VectorAssembler()
.setInputCols(dfIndexed.columns.diff(List("label") ++ categoricalColumns))
.setOutputCol("features")
Dopo l'applicazione del classificatore e pochi passaggi aggiuntivi alla fine con un frame di dati che ha un'etichetta, caratteristiche, e la previsione. Mi piacerebbe espandere il vettore delle mie funzionalità per separare le colonne per convertire i valori indicizzati nella loro forma String originale.
val categoryConverters = categoricalColumns.zip(categoryIndexers).map {
colAndIndexer => new IndexToString().setInputCol(s"${colAndIndexer._1}Indexed").setOutputCol(colAndIndexer._1).setLabels(colAndIndexer._2.fit(df).labels)
}
Domanda: C'è una semplice modo di fare questo , o è l'approccio migliore per attaccare in qualche modo la colonna previsione al telaio dati di test?
Quello che ho cercato:
val featureSlicers = categoricalColumns.map {
col => new VectorSlicer().setInputCol("features").setOutputCol(s"${col}Indexed").setNames(Array(s"${col}Indexed"))
}
Applicando questo mi dà le colonne che voglio, ma sono in forma vettoriale (in quanto è destinato a fare) e non tipo double.
Edit: L'uscita desiderata è il frame originale di dati (cioè funzioni categoriali come stringa non indice) con una colonna aggiuntiva che indica l'etichetta prevista (che nel mio caso è 0 o 1).
Per esempio, dicono che l'uscita del mio classificatore sembrava qualcosa di simile:
+-----+---------+----------+
|label| features|prediction|
+-----+---------+----------+
| 1.0|[0.0,3.0]| 1.0|
+-----+---------+----------+
Applicando VectorSlicer su ogni caratteristica vorrei avere:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| [0.0]| [3.0]|
+-----+---------+----------+-------------+-------------+
Che è grande, ma ho bisogno di:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| 0.0 | 3.0 |
+-----+---------+----------+-------------+-------------+
per poi essere in grado di utilizzare IndexToString e convertirlo in:
+-----+---------+----------+-------------+-------------+
|label| features|prediction| status | artist |
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| good | Pink Floyd |
+-----+---------+----------+-------------+-------------+
o anche:
+-----+----------+-------------+-------------+
|label|prediction| status | artist |
+-----+----------+-------------+-------------+
| 1.0| 1.0| good | Pink Floyd |
+-----+----------+-------------+-------------+
Ho un problema simile. Ho un set di dati di migliaia o colonne e alcuni di essi sono categoriali quindi devo "dividerli" in più colonne usando un 'StringIndexer' e' OneHotEncoder'. Il problema arriva quando cerco di realizzare ciò che rappresenta ogni caratteristica del vettore combinato. –
C'è qualche motivo per eliminare i dati di input in primo luogo? – zero323
Sì. La classificazione algo si aspetta un frame di dati con una colonna "label" e "feature". Dove la colonna caratteristica è un vettore, non è possibile avere stringhe. Per essere chiari, ho ancora il frame di dati originale con tutti i dati di input. – gstvolvr