Spark CountVectorizer return 一个 TinyInt

Spark CountVectorizer return a TinyInt

我首先在这个页面上问我的问题:

答案很正确。我还有一个问题,如果你清楚地检查我的 CountVectorizer 输出 格式如下:[0, 3, ...]

在我的 Databricks 笔记本中查看后,这行的格式似乎如下:

features` AS STRUCT<`type`: TINYINT, `size`: INT, `indices`: ARRAY<INT>, `values`: ARRAY<DOUBLE>>

但是在查看了 CountVectorizer 的 JavaDoc 之后,我发现 "type" 无处可去。

它是什么以及如何删除它? 因为这导致我

org.apache.spark.sql.AnalysisException: cannot resolve 'CAST(`features` AS STRUCT<`type`: TINYINT, `size`: INT, `indices`: ARRAY<INT>, `values`: ARRAY<DOUBLE>>)' due to data type mismatch: cannot cast vector to vector;

当我尝试将他转换为我的 LDA 的 RDD 时。

你混淆了两个不同的东西:

  • 列的架构类型和外部类型 - 在本例中分别为 org.apache.spark.ml.linalg.SQLDataTypes.VectorTypeorg.apache.spark.ml.linalg.Vector
  • UserDefinedType(其 sqlType)的内部表示。

UserDefinedTypeare in general not accessible 的内部属性。

您可以使用 to_json - from_json 技巧访问内部结构,类似于

所示
import org.apache.spark.sql.types._

val schema = StructType(Seq(StructField(
  "features", 
  StructType(Seq(
    StructField("indices", ArrayType(LongType, true), true), 
    StructField("size", LongType, true),
    StructField("type", ShortType, true), 
    StructField("values", ArrayType(DoubleType, true), true)
)), true)))

df.select(
  from_json(
    to_json(struct($"features")), schema
   ).getItem("features").alias("data")
)

但考虑到

i try to convert him to RDD for my LDA.

这只是浪费时间。如果您使用的是 Datasets,请使用新的 o.a.s.ml API,它已经提供了 LDA 实现。详情请参考官方文档中的示例 - Latent Dirichlet allocation (LDA)