【问题标题】:Spark and categorical string variablesSpark 和分类字符串变量
【发布时间】:2016-05-06 08:23:04
【问题描述】:

我试图了解 spark.ml 如何处理字符串分类自变量。我知道在 Spark 中我必须使用 StringIndexer 将字符串转换为双精度。
例如,“a”/“b”/“c” => 0.0/1.0/2.0。
但我真正想避免的是必须在双打列上使用OneHotEncoder。这似乎使管道不必要地混乱。特别是因为 Spark 知道数据是分类的。希望下面的示例代码能让我的问题更清楚。

import org.apache.spark.ml.feature.StringIndexer
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.ml.classification.LogisticRegression

val df = sqlContext.createDataFrame(Seq(
Tuple2(0.0,"a"), Tuple2(1.0, "b"), Tuple2(1.0, "c"), Tuple2(0.0, "c")
)).toDF("y", "x")

// index the string column "x"
val indexer = new StringIndexer().setInputCol("x").setOutputCol("xIdx").fit(df)
val indexed = indexer.transform(df)

// build a data frame of label, vectors
val assembler = (new VectorAssembler()).setInputCols(List("xIdx").toArray).setOutputCol("features")
val assembled = assembler.transform(indexed)

// build a logistic regression model and fit it
val logreg = (new LogisticRegression()).setFeaturesCol("features").setLabelCol("y")
val model = logreg.fit(assembled)

逻辑回归将此视为只有一个自变量的模型。

model.coefficients
res1: org.apache.spark.mllib.linalg.Vector = [0.7667490491775728]

但自变量是分类的,具有三个类别 = [“a”、“b”、“c”]。我知道我从未做过 k 编码之一,但数据帧的元数据知道特征向量是名义上的。

import org.apache.spark.ml.attribute.AttributeGroup
AttributeGroup.fromStructField(assembled.schema("features"))
res2: org.apache.spark.ml.attribute.AttributeGroup = {"ml_attr":{"attrs":
{"nominal":[{"vals":["c","a","b"],"idx":0,"name":"xIdx"}]},
"num_attrs":1}}

如何将此信息传递给LogisticRegression?这不是保留数据帧元数据的重点吗? SparkML 中似乎没有CategoricalFeaturesInfo。我真的需要对每个分类特征进行 1 of k 编码吗?

【问题讨论】:

  • 为什么不能直接在字符串上使用 one-hot 编码呢?一些模型明确允许分类特征,但逻辑回归需要连续特征(例如,a:0、b:1、c:2 的映射,暗示 c 是 b 的两倍)
  • OneHotEncoder 需要 DoubleType 列。另请参阅OneHotEncoder 的示例,他们首先使用 StringIndexer 进行转换,然后使用 OneHotEncoder。
  • 是的,您确实需要编码。
  • 很好地回答了我冗长的问题:)。在那种情况下,你能解释一下元数据的意义吗?这个向量的第一个条目实际上是一个名为“xIdx”且 vals = ["c", "a", "b"] 的名义变量这一事实将在哪里使用?
  • @zero323 它实际上现在用于提取树模型的信息。见here。 ml 和 mllib 实现之间的主要区别之一是“使用 DataFrame 元数据来区分连续和分类特征”

标签: apache-spark logistic-regression categorical-data apache-spark-ml


【解决方案1】:

也许我遗漏了一些东西,但这看起来确实像 RFormula (https://spark.apache.org/docs/latest/ml-features.html#rformula) 的工作。

顾名思义,它采用“R 风格”公式来描述特征向量是如何由输入数据列组成的。

对于每个分类输入列(即作为类型的 StringType),它会将 StringIndexer + OneHotEncoder 添加到最终实现公式的管道中。

输出是一个特征向量(双精度),可以与 org.apache.spark.ml 包中的任何算法一起使用,作为您的目标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-03-03
    • 1970-01-01
    • 2019-02-08
    • 2012-08-17
    • 1970-01-01
    • 2021-04-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多