从Pyspark LDA模型中提取文档主题矩阵

mou*_*hio 16 python lda apache-spark pyspark

我已经通过Python API在spark中成功训练了LDA模型:

from pyspark.mllib.clustering import LDA
model=LDA.train(corpus,k=10)
Run Code Online (Sandbox Code Playgroud)

这完全正常,但我现在需要LDA模型的文档 -主题矩阵,但据我所知,我能得到的是使用的单词 -topic model.topicsMatrix().

有没有办法从LDA模型中获取文档主题矩阵,如果没有,是否有一种替代方法(除了从零开始实现LDA)以运行LDA模型,它将为我提供我需要的结果?

编辑:

经过深入挖掘后,我在Java api中找到了DistributedLDAModel的文档topicDistributions(),我认为这正是我所需要的(但我敢肯定,如果Pyspark中的LDAModel实际上是一个在引擎盖下的DistributedLDAModel ...).

无论如何,我可以像这样间接调用这个方法,没有任何明显的失败:

In [127]: model.call('topicDistributions')
Out[127]: MapPartitionsRDD[3156] at mapPartitions at PythonMLLibAPI.scala:1480
Run Code Online (Sandbox Code Playgroud)

但是如果我真的看结果,我得到的只是字符串告诉我结果实际上是一个Scala元组(我认为):

In [128]: model.call('topicDistributions').take(5)
Out[128]:
[{u'__class__': u'scala.Tuple2'},
 {u'__class__': u'scala.Tuple2'},
 {u'__class__': u'scala.Tuple2'},
 {u'__class__': u'scala.Tuple2'},
 {u'__class__': u'scala.Tuple2'}]
Run Code Online (Sandbox Code Playgroud)

也许这通常是正确的方法,但有没有办法获得实际结果?

mou*_*hio 6

经过广泛的研究,这绝对不可能通过当前版本的Spark(1.5.1)上的Python api实现.但是在Scala中,它是相当简单的(给定一个RDD documents可以训练):

import org.apache.spark.mllib.clustering.{LDA, DistributedLDAModel}

// first generate RDD of documents...

val numTopics = 10
val lda = new LDA().setK(numTopics).setMaxIterations(10)
val ldaModel = lda.run(documents)

# then convert to distributed LDA model
val distLDAModel = ldaModel.asInstanceOf[DistributedLDAModel]
Run Code Online (Sandbox Code Playgroud)

然后获取文档主题分发就像这样简单:

distLDAModel.topicDistributions
Run Code Online (Sandbox Code Playgroud)


Jos*_*one 5

以下扩展了 PySpark 和 Spark 2.0 的上述响应。

我希望你能原谅我将此作为回复而不是作为评论发布,但我目前缺少代表。

我假设你有一个训练有素的 LDA 模型,它是由这样的语料库制成的:

lda = LDA(k=NUM_TOPICS, optimizer="em")
ldaModel = lda.fit(corpus) # Where corpus is a dataframe with 'features'.
Run Code Online (Sandbox Code Playgroud)

为了将文档转换为主题分布,我们创建了文档 ID 的数据框和单词的向量(稀疏更好)。

documents = spark.createDataFrame([
    [123myNumericId, Vectors.sparse(len(words_in_our_corpus), {index_of_word:count}],
    [2, Vectors.sparse(len(words_in_our_corpus), {index_of_word:count, another:1.0}],
], schema=["id", "features"]
transformed = ldaModel.transform(documents)
dist = transformed.take(1)
# dist[0]['topicDistribution'] is now a dense vector of our topics.
Run Code Online (Sandbox Code Playgroud)

  • 您能否分享您使用的完整代码..我在运行 hte 转换方法的 Pyspark 和 Spark 2.0 中遇到问题..(据说它不可用) (2认同)