如果我理解正确,您不想在几个虚拟列中转换 1 个分类列。您希望 spark 了解该列是分类的而不是数字的。
我认为这取决于您现在要使用的算法。例如随机森林和GBT都有categoricalFeaturesInfo作为参数在这里检查它:
https://spark.apache.org/docs/1.4.0/api/scala/index.html#org.apache.spark.mllib.tree.RandomForest$
例如:
categoricalFeaturesInfo = Map[Int, Int]((1,2),(2,5))
实际上是说你的特征的第二列(索引从 0 开始,所以 1 是第二列)是一个有 2 个级别的分类特征,第三个也是一个有 5 个级别的分类特征。您可以在训练 randomForest 或 GBT 时指定这些参数。
您需要确保您的级别映射到 0,1,2...所以如果您有类似 ("good","medium","bad") 之类的内容,请将其映射到 (0,1,2) .
现在,在您的情况下,您想使用 LogisticRegressionWithLBFGS。在这种情况下,我的建议是将分类列实际转换为虚拟列。例如,具有 3 个级别(“好”、“中”、“坏”)的单列分为 3 列,其中 1/0 取决于哪一个命中。我没有可以使用的示例,所以这里有一个 scala 中应该可以使用的示例代码:
val dummygen = (data : DataFrame, col:Array[String]) => {
var temp = data
for(i <- 0 until col.length) {
val N = data.select(col(i)).distinct.count.toInt
for (j<- 0 until N)
temp = temp.withColumn(col(i) + "_" + j.toString, callUDF(index(j), DoubleType, data(col(i))))
}
temp
}
val index = (value:Double) => {(a:Double) => {
if (value==a) {
1
} else{
0
}
}}
你可以这样称呼它:
val results = dummygen(data, Array("CategoricalColumn1","CategoricalColumn2"))
在这里,我为分类列列表执行此操作(以防万一您的功能列表中有超过 1 个)。第一个“for 循环”遍历每个分类列,第二个“for 循环”遍历列中的每个级别并创建与每列的级别数相等的列数。
重要!!!它假定您首先将它们映射到 0,1,2...
然后,您可以使用这个新功能集运行 LogisticRegressionWithLBFGS。这种方法也有助于 SVM。