我有一些新闻语料,我想用LDA来处理。为每个新闻文件提取关键字关键词也可以称为标签,表明这条新闻是关于什么的。
而不是用 tf-idf
,我在网上搜索了一下,觉得LDA可以更好地完成这项工作。
参考Spark文档。https:/spark.apache.orgdocslatestmllib-clustering.html#latent-dirichlet-allocation-lda。 而我发现 EMLDAOptimizer
产生 DistributedLDAModel
,它不仅存储推断的主题,还存储完整的训练语料和 每个文档的主题分布 训练语料库中。
分布式LDAModel支持。
而 OnlineLDAOptimizer
产生 LocalLDAModel
,其中 只存储推断的主题.
(来自mllib)
我有一些新闻语料,都是纯文本,大小在1.2G左右。经过标记化、去掉停顿词和所有的数据清洗过程(预处理)。我使用 CountVectorize
与 VocabSize
设置为200000和 LDA
与 K
设置为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
却找不到任何有关 topTopicsPerDocument
和 topDocumentsPerTopic
. 为什么这个和公文不一样呢?
还有这个方法 topicsMatrix
对于 DistributedLDAModel
,这到底是什么?我做了一些研究,认为 topicsMatrix
是每一个话题乘以每一个词汇在 countVectorizerModel.vocabulary
我不认为这 topicsMatrix
会有帮助。此外,这个矩阵中的一些数字是双倍大于1的,这让我很困惑。但这并不重要。
更重要的是 如何使用LDA为每个文档(新闻)提取不同的关键词??
关键词提取的任务是自动识别最能描述文档主题的术语。
K是你的新闻语料要聚类的主题数量。该 topicDistribution
每个文档的K-topics概率数组(基本上是告诉你哪个主题索引的概率最高)。然后你需要手动给K-topics打上标签(基于每个topics下的术语分组),因此你能够给文档打上 "标签"。
LDA不会根据文本给你一个 "标签",而是把相关的关键词聚类到所需的k-topics中去了