Gensim LDA中按主题分布的文档分布

3

在Python中,有没有一种方法可以将属于某个主题的文档映射起来。例如,一个主要是“主题0”的文档列表。我知道有办法列出每个文档的主题,但如何做到相反呢?

编辑:

我正在使用以下脚本进行LDA:

    doc_set = []
    for file in files:
        newpath = (os.path.join(my_path, file)) 
        newpath1 = textract.process(newpath)
        newpath2 = newpath1.decode("utf-8")
        doc_set.append(newpath2)

    texts = []
    for i in doc_set:
        raw = i.lower()
        tokens = tokenizer.tokenize(raw)
        stopped_tokens = [i for i in tokens if not i in stopwords.words()]
        stemmed_tokens = [p_stemmer.stem(i) for i in stopped_tokens]
        texts.append(stemmed_tokens)

    dictionary = corpora.Dictionary(texts)
    corpus = [dictionary.doc2bow(text) for text in texts]
    ldamodel = gensim.models.ldamodel.LdaModel(corpus, num_topics=2, random_state=0, id2word = dictionary, passes=1)

欢迎来到StackOverflow!请花些时间阅读如何提出好问题?,以及如何提供一个最小、完整和可验证的示例,并相应地修改您的问题。 - yatu
谁悄悄地删除了我的所有评论? - gojomo
1个回答

5
你有一个工具/API(Gensim LDA),给定一个文档,它会给你一个主题列表。
但是你希望得到反过来的结果:一个主题下的所有文档列表。
基本上,你需要自己构建反向映射。
幸运的是,Python内置的字典和映射相关的语法使这个过程非常简单 - 只需几行代码 - 只要处理的数据能完全放入内存中。
大致的做法如下:
- 创建一个新的结构(dict或list),用于将主题映射到文档列表。 - 遍历所有文档,将它们(也许带有分数)添加到主题到文档的映射中。 - 最后,查找(并可能排序)每个感兴趣主题的文档列表。
如果你的问题可以编辑包含更多关于文档/主题格式和ID以及如何训练LDA模型的信息,那么这个答案可以扩展为提供更具体的示例代码来构建所需的反向映射。
针对你代码更新的更新:
好的,如果你的模型在`ldamodel`中,你的BOW格式文档在`corpus`中,你可以这样做:
# setup: get the model's topics in their native ordering...
all_topics = ldamodel.print_topics()
# ...then create a empty list per topic to collect the docs:
docs_per_topic = [[] for _ in all_topics]

# now, for every doc...
for doc_id, doc_bow in enumerate(corpus):
    # ...get its topics...
    doc_topics = ldamodel.get_document_topics(doc_bow)
    # ...& for each of its topics...
    for topic_id, score in doc_topics:
        # ...add the doc_id & its score to the topic's doc list
        docs_per_topic[topic_id].append((doc_id, score))

在此之后,您可以像这样查看某个主题(例如主题0)的所有(doc_id, score)值列表:
print(docs_per_topic[0])

如果您对每个主题的顶级文档感兴趣,您可以通过其得分进一步排序每个列表中的一对文档:
for doc_list in docs_per_topic:
    doc_list.sort(key=lambda id_and_score: id_and_score[1], reverse=True)

那么,您可以获取主题0的前10个文档,如下所示:

print(docs_per_topic[0][:10])

请注意,这一切都是使用全内存列表完成的,对于非常大的语料库可能会变得不切实际。在某些情况下,您可能需要将每个主题清单编译成磁盘支持的结构,例如文件或数据库。

我已经编辑了我的问题,添加了我正在使用的脚本来运行gensim LDA。您能否查看它并建议我可以使用的代码?非常感谢。 - Eisenheim
非常感谢,它起作用了!只有一个小问题。我无法使用文档ID跟踪到我的文件夹中的文档。看起来gensim没有按照我的文件夹中的文档顺序分配文档ID。我已经尝试通过名称/类型/添加/修改重新排列文件夹中的文档,但它仍然与gensim不匹配。 - Eisenheim
如果您的文档仅通过文件名/文件路径进行标识,则需要记住自己的映射关系,将doc_id映射到原始文件路径。例如,您可以扩展代码以首先在顶部创建另一个list,如id_to_path = []。然后,在for file in files:循环内的底部,按照创建文档的顺序记住文件路径,并使用id_to_path.append[newpath]。最后,您可以查找id_to_path中的任何doc_id以查找原始文件。 - gojomo
谢谢。我已经按照您说的做了,但是仍然在努力找出如何查找文档ID并输出相应的路径/文件名。 - Eisenheim
当你的数据无法适应内存时该怎么办?不幸的是,这正是我的情况。 - Nina van Bruggen
如果您有关于不同主题的问题,例如如何在内存无法容纳的语料库上执行某些操作的方法,您应该发布一个单独的问题,并提供有关数据大小、系统限制以及要执行的具体操作的全部细节。 - gojomo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接