从spark中的分类列表创建一个热编码向量

olmpazwi  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(301)

如果我的数据包含5个类别(a、b、c、d、e)和一个客户数据集,其中每个客户可以属于一个、多个或不属于任何类别。如何获取这样的数据集:

id, categories
1 , [A,C]
2 , [B]
3 , []
4 , [D,E]

并将categories列转换为一个热编码向量,如下所示

id, categories, encoded
1 , [A,C]     , [1,0,1,0,0]
2 , [B]       , [0,1,0,0,0]
3 , []        , [0,0,0,0,0]
4 , [D,E]     , [0,0,0,1,1]

有没有人在spark找到了一个简单的方法?

clj7thdc

clj7thdc1#

为了获得所需的输出,您可以使用spark的udf(用户定义函数)扩展stephen carman answer:

// Prepare training documents from a list of (id, text, label) tuples.
val data = spark.createDataFrame(Seq(
  (0L, Seq("A", "B")),
  (1L, Seq("B")),
  (2L, Seq.empty),
  (3L, Seq("D", "E"))
)).toDF("id", "categories")

// Get distinct tags array
val tags = data
  .flatMap(r ⇒ r.getAs[Seq[String]]("categories"))
  .distinct()
  .collect()
  .sortWith(_ < _)

val cvmData = new CountVectorizerModel(tags)
  .setInputCol("categories")
  .setOutputCol("sparseFeatures")
  .transform(data)

val asDense = udf((v: Vector) ⇒ v.toDense)

cvmData
  .withColumn("features", asDense($"sparseFeatures"))
  .select("id", "categories", "features")
  .show()

这将给你想要的输出

+---+----------+-----------------+
| id|categories|         features|
+---+----------+-----------------+
|  0|    [A, B]|[1.0,1.0,0.0,0.0]|
|  1|       [B]|[0.0,1.0,0.0,0.0]|
|  2|        []|[0.0,0.0,0.0,0.0]|
|  3|    [D, E]|[0.0,0.0,1.0,1.0]|
+---+----------+-----------------+
mw3dktmi

mw3dktmi2#

一些非常容易做的事情,这在某种程度上是相同的是使用countvectorizermodel

val df = spark.createDataFrame(Seq(
  (1, Seq("A","C")),
  (2, Seq("B")),
  (3, Seq()),
  (4, Seq("D","E")))
).toDF("id", "category")

val cvm = new CountVectorizerModel(Array("A","B","C","D","E"))
  .setInputCol("category")
  .setOutputCol("features")

cvm.transform(df).show()

/*
+---+--------+-------------------+
| id|category|           features|
+---+--------+-------------------+
|  1|  [A, C]|(5,[0,2],[1.0,1.0])|
|  2|     [B]|      (5,[1],[1.0])|
|  3|      []|          (5,[],[])|
|  4|  [D, E]|(5,[3,4],[1.0,1.0])|
+---+--------+-------------------+

* /

这与您想要的并不完全相同,但是特征向量将告诉您数据中存在哪些类别。例如,在第1行中,[0,2]对应于字典的第一个和第三个元素,或者这里写的“a”和“c”。

相关问题