scala - 使用一种热编码和向量汇编器与向量索引器来处理分类特征

标签 scala apache-spark machine-learning categorical-data apache-spark-ml

假设我在数据框中有分类特征。为了在数据帧上进行机器学习,我使用 OneHotEncoderEstimator() 对分类列进行一次热编码,然后使用 VectorAssembler() 将所有功能组装成一个柱子。读Spark时docs我已经看到使用 VectorIndexer() 来索引特征向量列中的分类特征。如果我在制定特征向量列之前已经对分类列执行了一项热编码,那么在其上应用 VectorIndexer() 是否有任何意义。

最佳答案

OneHotEncoder(Estimator)VectorIndexer 是完全不同的野兽,并且不可互换。 OneHotEncoder(Estimator) 主要在下游流程使用线性模型 ( it can be also used with Naive Bayes ) 时使用。

让我们考虑一个简单的数据集

val df = Seq(1.0, 2.0, 3.0).toDF

和一个管道

import org.apache.spark.ml.Pipeline
import org.apache.spark.ml.feature._

val m1 = new Pipeline().setStages(Array(
  new OneHotEncoderEstimator()
   .setInputCols(Array("value")).setOutputCols(Array("features"))
)).fit(df)

如果这样的模型应用于我们的数据,它将是one-hot-encoded(取决于配置OneHotEncoderEstimator支持one-hot-encoding和dummy编码) - 换句话说,每个级别,排除引用将是表示为单独的二进制列:

m1.transform(df).schema("features").metadata
 org.apache.spark.sql.types.Metadata = {"ml_attr":{"attrs":{"binary":[{"idx":0,"name":"0"},{"idx":1,"name":"1"},{"idx":2,"name":"2"}]},"num_attrs":3}}

请注意,这种表示方法对于本地处理分类特征的算法来说效率低下且不切实际。

相比之下,VectorIndexer 仅分析数据,并相应地调整元数据

val m2 = new Pipeline().setStages(Array(
  new VectorAssembler().setInputCols(Array("value")).setOutputCol("raw"),
  new VectorIndexer().setInputCol("raw").setOutputCol("features")
)).fit(df)

m2.transform(df).schema("features").metadata
org.apache.spark.sql.types.Metadata = {"ml_attr":{"attrs":{"nominal":[{"ord":false,"vals":["1.0","2.0","3.0"],"idx":0,"name":"value"}]},"num_attrs":1}}

换句话说,它或多或少相当于 StringIndexer 的矢量化变体(您可以通过使用一组 StringIndexers 后跟 来实现类似的结果,并对输出进行更多控制VectorAssembler)。

此类特征是 unsuitable for linear models ,但它们是决策树和树集成的有效输入。

总结 - 在实践中,OneHotEncoder(Esitmator)VectorIndexer 是互斥的,应选择使用哪一个取决于下游流程。

关于scala - 使用一种热编码和向量汇编器与向量索引器来处理分类特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54222750/

相关文章:

scala - 在 Slurm 上运行 Spark

python - PySpark DecisionTree 模型的精度和召回率与手动结果存在差异

scala - 了解 UID 在 Spark MLLib Transformer 中的作用

matlab - GMModel - 如何使用它来预测标签的数据?

apache-spark - Spark (1.6) ML 线性回归 - 如何使用模型进行预测

r - 使用 nnet 进行预测,我这样做对吗?

java - scala.Some 无法转换为自定义对象

java - 进程输出是否以 EOF 结尾,如果是,如何删除?

scala - 如何使用Scala actor充分利用所有核心?

scala - 为什么这个谓词中的参数可以省略呢?