gpt4 book ai didi

apache-spark - Spark.ml LogisticRegression 是否仅假设数值特征?

转载 作者:行者123 更新时间:2023-12-04 04:07:43 24 4
gpt4 key购买 nike

我正在查看 Spark 1.5 dataframe/row apiimplementation对于逻辑回归。据我了解,其中的 train 方法首先将 dataframe 转换为 RDD[LabeledPoint] 作为,

override protected def train(dataset: DataFrame): LogisticRegressionModel = {
// Extract columns from data. If dataset is persisted, do not persist oldDataset.
val instances = extractLabeledPoints(dataset).map {
case LabeledPoint(label: Double, features: Vector) => (label, features)
}
...

然后进行特征标准化等

让我感到困惑的是,DataFrame 的类型是 RDD[Row] 并且 Row 允许有任何 valueTypes,例如(1, true, "a string", null) 似乎是数据框的有效行。如果是这样,上面的 extractLabeledPoints 是什么意思?它似乎只选择 Array[Double] 作为 Vector 中的特征值。如果数据框中的列是 strings 会怎样?另外,整数分类值会怎样?

提前致谢,尼克尔

最佳答案

让我们暂时忽略 Spark。一般来说,包括逻辑回归在内的线性模型都需要数值自变量。它不以任何方式特定于 Spark/MLlib。如果输入包含分类或有序变量,则必须首先对这些变量进行编码。一些语言,如 R,以透明的方式处理这个问题:

> df <- data.frame(x1 = c("a", "b",  "c", "d"), y=c("aa", "aa", "bb", "bb"))
> glm(y ~ x1, df, family="binomial")

Call: glm(formula = y ~ x1, family = "binomial", data = df)

Coefficients:
(Intercept) x1b x1c x1d
-2.357e+01 -4.974e-15 4.713e+01 4.713e+01
...

但真正在幕后使用的是所谓的设计矩阵:

> model.matrix( ~ x1, df)
(Intercept) x1b x1c x1d
1 1 0 0 0
2 1 1 0 0
3 1 0 1 0
4 1 0 0 1
...

跳过细节,它与 Spark 中的 OneHotEncoder 执行的转换类型相同。

import org.apache.spark.mllib.linalg.Vector
import org.apache.spark.ml.feature.{OneHotEncoder, StringIndexer}

val df = sqlContext.createDataFrame(Seq(
Tuple1("a"), Tuple1("b"), Tuple1("c"), Tuple1("d")
)).toDF("x").repartition(1)

val indexer = new StringIndexer()
.setInputCol("x")
.setOutputCol("xIdx")
.fit(df)

val indexed = indexer.transform(df)

val encoder = new OneHotEncoder()
.setInputCol("xIdx")
.setOutputCol("xVec")

val encoded = encoder.transform(indexed)

encoded
.select($"xVec")
.map(_.getAs[Vector]("xVec").toDense)
.foreach(println)

Spark 更进一步,所有特征,即使算法允许名义/有序自变量,也必须使用 spark.mllib.linalg.Vector 存储为 Double >。在 spark.ml 中,它是一个 DataFrame 列,在 spark.mllib 中,它是 spark.mllib.regression.LabeledPoint 中的一个字段

不过,根据模型对特征向量的解释可能会有所不同。正如上面提到的线性模型,这些将被解释为数值变量。对于 Naive Bayes,这些被认为是名义上的。如果模型接受数值变量和名义变量 Spark 并以不同的方式对待每个组,如决策/回归树,您可以提供 categoricalFeaturesInfo参数。

值得指出的是,因变量也应编码为 Double,但与自变量不同,可能需要额外的元数据才能正确处理。如果您查看 indexed DataFrame,您会发现 StringIndexer 不仅转换 x,还添加了属性:

scala> org.apache.spark.ml.attribute.Attribute.fromStructField(indexed.schema(1))
res12: org.apache.spark.ml.attribute.Attribute = {"vals":["d","a","b","c"],"type":"nominal","name":"xIdx"}

最后是来自 ML 的一些 Transformers,例如 VectorIndexer ,可以根据不同值的数量自动检测和编码分类变量。

关于apache-spark - Spark.ml LogisticRegression 是否仅假设数值特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32387015/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com