基于LDA的get_document_topics批量为数据框行分配主题
问题
我有一个预处理后的在线评论数据集,每行是一条评论的分词结果。现在用gensim的Latent Dirichlet Allocation(LDA)提取主题,需要用get_document_topics函数给每行分配主题,把各主题概率和最匹配的主题列添加到原DataFrame里。
现有示例代码只能处理单篇文档:
text = ["user"] bow = dictionary.doc2bow(text) print("get_document_topics", model.get_document_topics(bow)) # 输出:get_document_topics [(0, 0.7456841580694633), (1, 0.25431584193053675)]
期望的DataFrame输出格式:
stemming probabOnTopic1 probOnTopic2 probaOnTopic3 topic 0 [bank, water, bank] 0.7 0.3 0.0 0 1 [baseball, rain, track] 0.1 0.8 0.1 1 2 [coin, money, money] 0.9 0.0 0.1 0 3 [vote, elect, bank] 0.2 0.0 0.8 2
我自己写的代码有问题,无法实现需求:
def bow (text): return [dictionary.doc2bow(text) in document] df["probability"] = optimal_model.get_document_topics(bow) df[['probOnTopic1', 'probOnTopic2', 'probOnTopic3']] = pd.DataFrame(df['probability'].tolist(), index=df.index)
解决方案
问题分析
你写的代码存在几个关键错误:
bow函数逻辑错误,[dictionary.doc2bow(text) in document]完全不符合词袋转换的逻辑,应该是对单个分词列表生成词袋向量- 直接把
bow函数传给get_document_topics是错误的,该函数需要接收词袋向量的迭代器,而不是函数本身 - 没有处理
get_document_topics返回的稀疏结果(部分低概率主题不会被返回,需要补0)
完整实现代码
假设你的DataFrame中存储分词结果的列名为stemming,LDA模型有3个主题:
import pandas as pd # 1. 为每行生成词袋向量 df['bow'] = df['stemming'].apply(lambda x: dictionary.doc2bow(x)) # 2. 批量获取所有文档的主题概率 # 设置minimum_probability=0确保返回所有主题的概率,避免稀疏结果 topic_probs = optimal_model.get_document_topics(df['bow'], minimum_probability=0) # 3. 将主题概率转换为有序的DataFrame列 # 按主题ID排序,确保概率值与主题列一一对应 topic_prob_list = [[prob for _, prob in sorted(probs, key=lambda x: x[0])] for probs in topic_probs] # 生成主题概率列名 topic_cols = [f'probOnTopic{i+1}' for i in range(optimal_model.num_topics)] df[topic_cols] = pd.DataFrame(topic_prob_list, index=df.index) # 4. 生成最匹配的主题列(取概率最大的主题ID) df['topic'] = df[topic_cols].idxmax(axis=1).str.replace('probOnTopic', '').astype(int) # 可选:删除临时生成的bow列 df.drop('bow', axis=1, inplace=True)
代码说明
- 用
apply对每行的分词列表批量生成词袋向量,这是正确的批量转换方式 minimum_probability=0强制返回所有主题的概率,避免因稀疏结果导致列对齐错误- 对每个文档的主题概率按主题ID排序,保证概率值与主题列的顺序一致
- 通过
idxmax获取概率最高的主题,转换为整数类型的主题ID
内容的提问来源于stack exchange,提问作者Dewani
相关产品推荐
相关产品推荐

