作者主题模型(Author-Topic Model)的Python Gensim实现

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. 完整实现


1. ATM模型原理

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

2. Author-Topic Model的英文文档

models.atmodel – Author-topic models — gensim (radimrehurek.com)https://radimrehurek.com/gensim/models/atmodel.html

3. Python调用Gensim的实现过程

3.1 导入相关包

from gensim.corpora import Dictionary
from gensim.models import AuthorTopicModel

3.2 准备数据

ATM模型需要的数据主要包括:

  1. 每篇文章的分词列表
  2. 每篇文章的作者列表(相比LDA模型需要额外准备的数据)
  3. 作者与文章(下标)的对应关系(通过转换得到)
# 这里是使用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]}

3.3 文本向量化

这里采用的是词袋模型,将每一篇文章转换为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]

3.4 模型训练

训练ATM模型,如果数据量较大可能需要比较久的时间,其中num_topics参数可以设定目标的主题个数,这里为10。

atm = AuthorTopicModel(corpus, num_topics=10, author2doc=author2doc, id2word=dictionary)

3.5 模型结果输出 

获取每个主题的主题词及其权重,其中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)}

3.6 模型保存和载入

保存模型训练结果,需要注意的是模型文件不止一个,载入时也需要保持完整,不可删除。

atm.save('atm.model')

载入模型

atm = AuthorTopicModel.load('atm.model')

4. 完整实现

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')  # 保存模型

你可能感兴趣的:(自然语言处理(NLP),python,自然语言处理)