我应该如何在Spark LDA中获取每个文档的主题?

问题描述 投票:0回答:1

我的目标是

我有一些新闻语料,我想用LDA来处理。为每个新闻文件提取关键字关键词也可以称为标签,表明这条新闻是关于什么的。

而不是用 tf-idf,我在网上搜索了一下,觉得LDA可以更好地完成这项工作。

我们先来定义一些Terminologies。

  • "term"="word": 词汇的一个元素。
  • "标记":文件中出现的术语实例
  • "主题":代表某种概念的术语的多项分布。
  • "文档":一段文字,对应输入数据中的一行。

我觉得SAPRK LDA怎么样

参考Spark文档。https:/spark.apache.orgdocslatestmllib-clustering.html#latent-dirichlet-allocation-lda。 而我发现 EMLDAOptimizer 产生 DistributedLDAModel,它不仅存储推断的主题,还存储完整的训练语料和 每个文档的主题分布 训练语料库中。

分布式LDAModel支持。

  • topTopicsPerDocument。训练语料库中每个文档的顶级主题及其权重。
  • topDocumentsPerTopic。每个主题的顶级文档以及该主题在文档中的相应权重。

OnlineLDAOptimizer 产生 LocalLDAModel,其中 只存储推断的主题.

(来自mllib)

那就看看我都做了些什么吧

我有一些新闻语料,都是纯文本,大小在1.2G左右。经过标记化、去掉停顿词和所有的数据清洗过程(预处理)。我使用 CountVectorizeVocabSize 设置为200000和 LDAK 设置为15。maxiter 到100。optimizer 到 "他们"。CheckpointInterval 到10,其他未提及的参数为默认值。这2个 Transformer的被放入Pipeline中进行训练。

(来自ml)

    val countVectorizer = new CountVectorizer()
      .setInputCol("content_clean_cut")
      .setOutputCol("count_vector")
      .setVocabSize(200000)
    val lda = new LDA()
      .setK(15)
      .setMaxIter(100)
      .setFeaturesCol("count_vector")
      .setOptimizer("em")
      .setCheckpointInterval(10)
    val pipeline = new Pipeline()
      .setStages(Array(countVectorizer, lda))
    val ldaModel = pipeline.fit(newsDF)
    ldaModel.write.overwrite().save("./news_lda.model")

用300G左右的内存把作业发到spark-submit,终于训练成功了。

然后,我开始使用这个管道模型对预处理后的新闻语料进行转化,即为 show() 是。

+------------------------------+----+--------------------+--------------------+
|             content_clean_cut| cls|        count_vector|   topicDistribution|
+------------------------------+----+--------------------+--------------------+
|  [深锐, 观察, 科比, 只想, ...|体育|(200000,[4,6,9,11...|[0.02062984049807...|
| [首届, 银联, 网络, 围棋赛,...|体育|(200000,[2,4,7,9,...|[0.02003532045153...|
|[董希源, 国米, 必除, 害群之...|体育|(200000,[2,4,9,11...|[0.00729266918401...|
| [李晓霞, 破茧, 成蝶, 只差,...|体育|(200000,[2,4,7,13...|[0.01200369382233...|
|  [深锐, 观察, 对手, 永远, ...|体育|(200000,[4,9,13,1...|[0.00613485655279...|

是: 模式。

root
 |-- content_clean_cut: array (nullable = true)
 |    |-- element: string (containsNull = true)
 |-- cls: string (nullable = true)
 |-- count_vector: vector (nullable = true)
 |-- topicDistribution: vector (nullable = true)

我不明白这是什么 topicDistribution 列的意思,为什么它的长度是 K,就是意味着最大数的索引就是这个文档(新闻)的主题索引,所以我们可以通过找到最大数的索引来推断这个文档的主题,而这个索引其实就是主题中的索引。describeTopics() 方法返回?

将管道中的第二阶段投向 DistributedLDAModel 却找不到任何有关 topTopicsPerDocumenttopDocumentsPerTopic. 为什么这个和公文不一样呢?

还有这个方法 topicsMatrix 对于 DistributedLDAModel,这到底是什么?我做了一些研究,认为 topicsMatrix 是每一个话题乘以每一个词汇在 countVectorizerModel.vocabulary我不认为这 topicsMatrix 会有帮助。此外,这个矩阵中的一些数字是双倍大于1的,这让我很困惑。但这并不重要。

更重要的是 如何使用LDA为每个文档(新闻)提取不同的关键词??

关键词提取的任务是自动识别最能描述文档主题的术语。

apache-spark keyword lda
1个回答
1
投票

K是你的新闻语料要聚类的主题数量。该 topicDistribution 每个文档的K-topics概率数组(基本上是告诉你哪个主题索引的概率最高)。然后你需要手动给K-topics打上标签(基于每个topics下的术语分组),因此你能够给文档打上 "标签"。

LDA不会根据文本给你一个 "标签",而是把相关的关键词聚类到所需的k-topics中去了

© www.soinside.com 2019 - 2024. All rights reserved.