Почему StandardScaler не прикрепляет метаданные к выходному столбцу?
Я заметил, что мл StandardScaler
не прикрепляет метаданные к выходному столбцу:
import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.feature._
val df = spark.read.option("header", true)
.option("inferSchema", true)
.csv("/path/to/cars.data")
val strId1 = new StringIndexer()
.setInputCol("v7")
.setOutputCol("v7_IDX")
val strId2 = new StringIndexer()
.setInputCol("v8")
.setOutputCol("v8_IDX")
val assmbleFeatures: VectorAssembler = new VectorAssembler()
.setInputCols(Array("v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7_IDX"))
.setOutputCol("featuresRaw")
val scalerModel = new StandardScaler()
.setInputCol("featuresRaw")
.setOutputCol("scaledFeatures")
val plm = new Pipeline()
.setStages(Array(strId1, strId2, assmbleFeatures, scalerModel))
.fit(df)
val dft = plm.transform(df)
dft.schema("scaledFeatures").metadata
дает:
res1: org.apache.spark.sql.types.Metadata = {}
Этот пример работает с этим набором данных (просто измените путь в коде выше).
Есть ли конкретная причина для этого? Вполне вероятно, что эта функция будет добавлена в Spark в будущем? Любые предложения для обходного пути, который не включает дублирование StandardScaler?
1 ответ
Хотя отбрасывание метаданных, вероятно, не самый удачный выбор, масштабирование индексированных категориальных функций не имеет никакого смысла. Значения, возвращаемые StringIndexer
это просто ярлыки.
Если вы хотите масштабировать числовые объекты, это должен быть отдельный этап:
val numericAssembler: VectorAssembler = new VectorAssembler()
.setInputCols(Array("v0", "v1", "v2", "v3", "v4", "v5", "v6"))
.setOutputCol("numericFeatures")
val scaler = new StandardScaler()
.setInputCol("numericFeatures")
.setOutputCol("scaledNumericFeatures")
val finalAssembler: VectorAssembler = new VectorAssembler()
.setInputCols(Array("scaledNumericFeatures", "v7_IDX"))
.setOutputCol("features")
new Pipeline()
.setStages(Array(strId1, strId2, numericAssembler, scaler, finalAssembler))
.fit(df)