Gensim中的主题模型包括三种,分别是LDA (Latent Dirichlet Allocation) 主题模型、加入了作者因素的作者主题模型 (Author-Topic Model, ATM) 和加入了时间因素的动态主题模型 (Dynamic Topic Models, DTM) 。
作者主题模型(ATM)的输入除了分词后的文章内容,还包括作者和文章的对应关系;模型的输出为每位作者对于每个主题(主题数n可以自己设定)的倾向度。
LDA主题模型在许多研究中都已广泛应用,在网上也有相当多的程序资料,但ATM模型的相关代码资料却不甚完整,在前段时间比赛查找资料的过程中也遇到了一些困扰,后来看了英文的官方文档才得以解决。因此本文介绍Gensim包中ATM模型完整实现的过程,完整代码附在最后。
目录
1. ATM模型原理
2. Author-Topic Model的英文文档
3. Python调用Gensim的实现过程
3.1 导入相关包
3.2 准备数据
3.3 文本向量化
3.4 模型训练
3.5 模型结果输出
3.6 模型保存和载入
4. 完整实现
Author Topic Model解析_chinaliping的博客-CSDN博客https://blog.csdn.net/chinaliping/article/details/9299953
Author Topic Model[ATM理解及公式推导]_HFUT_qianyang的博客-CSDN博客参考论文Modeling documents with topicsModeling authors with wordsThe author-topic modelGibbs sampling algorithms详细经典LDA模型目标分布及参数Author Model目标分布及参数Author-topic model目标分布及参数本文作者:合肥工业大学 管理学院 钱洋 email:https://qianyang-hfut.blog.csdn.net/article/details/54407099
models.atmodel – Author-topic models — gensim (radimrehurek.com)https://radimrehurek.com/gensim/models/atmodel.html
from gensim.corpora import Dictionary
from gensim.models import AuthorTopicModel
ATM模型需要的数据主要包括:
# 这里是使用pandas的DataFrame来读取csv表格中的数据,其中包含分词、作者等信息。
import pandas as pd
df = pd.read_csv('data.csv')
# 数据中的“分词”列是用空格分隔的词语,如果数据没有分词,还需要使用jieba等分词工具进行分词
df['分词'] = df['分词'].map(lambda x: x.split()) # 用split还原成列表
data = df['分词'].values.tolist() # 每篇文章的分词列表,每个内层列表包含一篇文章的内容
# 示例:[['我', '喜欢', '猫'], ['他', '喜欢', '狗'], ['我们', '喜欢', '动物']]
author = df['作者'].values.tolist() # 每篇文章的作者列表
# 示例:['作者1', '作者2', '作者1']
# 将作者和文章的对应关系转换为模型需要的格式
author2doc = {}
for idx, au in enumerate(author):
if au in author2doc.keys():
author2doc[au].append(idx)
else:
author2doc[au] = [idx]
# 转换后示例:{'作者1': [0, 2], '作者2': [1]}
这里采用的是词袋模型,将每一篇文章转换为BOW (Bag of words) 向量,可以用filter_n_most_frequent()过滤高频词。
dictionary = Dictionary(data)
dictionary.filter_n_most_frequent(50) # 过滤最高频的50个词
corpus = [dictionary.doc2bow(text) for text in data]
训练ATM模型,如果数据量较大可能需要比较久的时间,其中num_topics参数可以设定目标的主题个数,这里为10。
atm = AuthorTopicModel(corpus, num_topics=10, author2doc=author2doc, id2word=dictionary)
获取每个主题的主题词及其权重,其中num_words参数可以控制每个主题输出的主题词数量。
atm.print_topics(num_words=20)
获取某位作者的主题分布
atm.get_author_topics('作者1')
每位作者的主题分布
author_topics = {au: atm.get_author_topics(au) for au in set(author)}
保存模型训练结果,需要注意的是模型文件不止一个,载入时也需要保持完整,不可删除。
atm.save('atm.model')
载入模型
atm = AuthorTopicModel.load('atm.model')
from gensim.corpora import Dictionary
from gensim.models import AuthorTopicModel
import pandas as pd
df = pd.read_csv('data.csv')
# 数据中的“分词”列是用空格分隔的词语,如果数据没有分词,还需要使用jieba等分词工具进行分词
df['分词'] = df['分词'].map(lambda x: x.split()) # 用split还原成列表
data = df['分词'].values.tolist() # 每篇文章的分词列表
author = df['作者'].values.tolist() # 每篇文章的作者列表
# 将作者和文章的对应关系转换为模型需要的格式
author2doc = {}
for idx, au in enumerate(author):
if au in author2doc.keys():
author2doc[au].append(idx)
else:
author2doc[au] = [idx]
# 文本向量化
dictionary = Dictionary(data)
dictionary.filter_n_most_frequent(50) # 过滤最高频的50个词
corpus = [dictionary.doc2bow(text) for text in data]
atm = AuthorTopicModel(corpus, num_topics=10, author2doc=author2doc, id2word=dictionary)
atm.print_topics(num_words=20) # 打印每个主题前20个主题词
author_topics = {au: atm.get_author_topics(au) for au in set(author)} # 作者主题分布
atm.save('atm.model') # 保存模型