【问题标题】:Can't run LDA on Dataset[(scala.Long, org.apache.spark.mllib.linalg.Vector)] in Spark 2.0无法在 Spark 2.0 中的数据集 [(scala.Long, org.apache.spark.mllib.linalg.Vector)] 上运行 LDA
【发布时间】:2016-12-12 21:56:57
【问题描述】:

我正在关注关于 LDA 示例的 this 教程视频,但遇到以下问题:

<console>:37: error: overloaded method value run with alternatives:
  (documents: org.apache.spark.api.java.JavaPairRDD[java.lang.Long,org.apache.spark.mllib.linalg.Vector])org.apache.spark.mllib.clustering.LDAModel <and>
  (documents: org.apache.spark.rdd.RDD[(scala.Long, org.apache.spark.mllib.linalg.Vector)])org.apache.spark.mllib.clustering.LDAModel
  cannot be applied to (org.apache.spark.sql.Dataset[(scala.Long, org.apache.spark.mllib.linalg.Vector)])
     val model = run(lda_countVector)
                                   ^

所以我想将此 DF 转换为 RDD,但它总是为我分配为 DataSet。有人可以看看这个问题吗?

// Convert DF to RDD
import org.apache.spark.mllib.linalg.Vector
val lda_countVector = countVectors.map { case Row(id: Long, countVector: Vector) => (id, countVector) }
// import org.apache.spark.mllib.linalg.Vector
// lda_countVector: org.apache.spark.sql.Dataset[(Long, org.apache.spark.mllib.linalg.Vector)] = [_1: bigint, _2: vector]

【问题讨论】:

  • 你能给我们countVectors的类型吗?
  • countVectors.printSchema ​ root |-- id: long (nullable = false) |-- features: vector (nullable = true)
  • 这不是类型而是架构。
  • 哦,那是一个数据框 - countVectors: org.apache.spark.sql.DataFrame = [id: bigint, features: vector]

标签: scala apache-spark apache-spark-mllib


【解决方案1】:

Spark API 在 1.x 和 2.x 分支之间发生了变化。特别是 DataFrame.map 返回 Dataset 而不是 RDD 因此结果与旧的基于 MLlib RDD 的 API 不兼容。您应该首先将数据转换为RDD,如下所示:

import org.apache.spark.mllib.linalg.Vectors
import org.apache.spark.sql.Row
import org.apache.spark.mllib.linalg.Vector
import org.apache.spark.mllib.clustering.{DistributedLDAModel, LDA}

val a = Vectors.dense(Array(1.0, 2.0, 3.0))
val b = Vectors.dense(Array(3.0, 4.0, 5.0))
val df = Seq((1L ,a), (2L, b), (2L, a)).toDF

val ldaDF = df.rdd.map { 
  case Row(id: Long, countVector: Vector) => (id, countVector) 
} 

val model = new LDA().setK(3).run(ldaDF)

或者您可以转换为类型化数据集,然后再转换为 RDD:

val model = new LDA().setK(3).run(df.as[(Long, Vector)].rdd)

【讨论】:

  • 感谢 eliasah 关注此问题,感谢!我试图实现这个建议,现在它给了我另一个例外drive.google.com/open?id=0B8NpxtKK8m-8QzF5Ymg0aXRqRXc。但是当我执行你的代码时它工作正常,所以我会投票并将你的建议标记为答案。如果我在我的数据中发现问题,我会回复这个帖子。
  • 这似乎是 Scala 版本错误。检查集群是否运行与您相同版本的 Scala。
  • 集群在 Spark 2.0 Scala 2.10
  • 嗨 @eliasah 有没有办法将 CountVectorizer 转换为密集向量。我相信 LDA 会抛出异常,因为 CountVectorizer 是给定稀疏向量。这就是为什么它似乎在你的例子中运行良好,但在我的例子中却不是。
  • 哇,这对我有帮助!非常感谢 SSCE!
猜你喜欢
  • 2017-06-01
  • 2014-08-25
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-10
  • 1970-01-01
相关资源
最近更新 更多