Применение IndexToString к вектору объектов в Spark
Контекст: У меня есть фрейм данных, где все категориальные значения были проиндексированы с использованием StringIndexer.
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")
}
Затем я использовал VectorAssembler для векторизации всех столбцов объектов (включая индексированные категориальные).
val assembler = new VectorAssembler()
.setInputCols(dfIndexed.columns.diff(List("label") ++ categoricalColumns))
.setOutputCol("features")
После применения классификатора и нескольких дополнительных шагов я получаю фрейм данных, который имеет метку, характеристики и прогноз. Я хотел бы расширить вектор объектов на отдельные столбцы, чтобы преобразовать индексированные значения обратно в их исходную строковую форму.
val categoryConverters = categoricalColumns.zip(categoryIndexers).map {
colAndIndexer => new IndexToString().setInputCol(s"${colAndIndexer._1}Indexed").setOutputCol(colAndIndexer._1).setLabels(colAndIndexer._2.fit(df).labels)
}
Вопрос: Есть липросто способ сделать это, или это лучший способ каким-то образом прикрепить столбец прогнозирования к фрейму тестовых данных?
Что я пробовал:
val featureSlicers = categoricalColumns.map {
col => new VectorSlicer().setInputCol("features").setOutputCol(s"${col}Indexed").setNames(Array(s"${col}Indexed"))
}
Применение этого дает мне столбцы, которые я хочу, но они в векторной форме (как это и должно быть), а не типа Double.
Редактировать: Желаемый вывод - это исходный фрейм данных (т. Е. Категорическое свойство, res как строка, а не индекс) с дополнительным столбцом, указывающим прогнозируемую метку (которая в моем случае равна 0 или 1).
Например, скажем, вывод моего классификатора выглядел примерно так:
+-----+---------+----------+
|label| features|prediction|
+-----+---------+----------+
| 1.0|[0.0,3.0]| 1.0|
+-----+---------+----------+
Применяя VectorSlicer к каждой функции, я получу:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| [0.0]| [3.0]|
+-----+---------+----------+-------------+-------------+
Что здорово, но мне нужно:
+-----+---------+----------+-------------+-------------+
|label| features|prediction|statusIndexed|artistIndexed|
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| 0.0 | 3.0 |
+-----+---------+----------+-------------+-------------+
Чтобы затем иметь возможность использовать IndexToString и преобразовать его в:
+-----+---------+----------+-------------+-------------+
|label| features|prediction| status | artist |
+-----+---------+----------+-------------+-------------+
| 1.0|[0.0,3.0]| 1.0| good | Pink Floyd |
+-----+---------+----------+-------------+-------------+
или даже:
+-----+----------+-------------+-------------+
|label|prediction| status | artist |
+-----+----------+-------------+-------------+
| 1.0| 1.0| good | Pink Floyd |
+-----+----------+-------------+-------------+