NLP实验——LDA主题模型

原理

原理我就不细致讨论啦,放上几个比较好的博客

  1. yang_guo 机器学习-LDA主题模型笔记
  2. 致Great NLP系列(三)LDA主题模型
  3. 刘建平Pinard 文本主题模型之LDA(一) LDA基础

我的理解比较简单:因为有一词多义的存在,通过建立词和主题之间的联系,通过Gibbs抽样,实现降维(将文档降维到主题)。

gensim实现

简单来说LDA实现主要几个步骤

  1. 文本切词
  2. 生成词典
  3. doc2bow:就是词——>稀疏向量集
  4. 调用gensim中的LDA模型

完整代码如下:

# 导入库
import os
import jieba  # 分词模块
from gensim import corpora, models  # gensim的词频统计和主题建模模块

# 构建停词库
def get_custom_stopwords(stop_words_file):
    with open(stop_words_file,encoding='UTF-8') as f:
        stopwords = f.read()
    stopwords_list = stopwords.split('\n')
    custom_stopwords_list = [i for i in stopwords_list]
    return custom_stopwords_list

# 文件夹文件读取
print('读取文件并获取内容...')
all_content = []  # 总列表,用于存储所有文件的文本内容
for root, dirs, files in os.walk('../清洗过'):  # 分别读取遍历目录下的根目录、子目录和文件列表
    for file in files:  # 读取每个文件
        file_name = os.path.join(root, file)  # 将目录路径与文件名合并为带有完整路径的文件名
        with open(file_name, encoding='utf-8') as f:  # 以只读方式打开文件
            data = f.read()  # 读取文件内容
            words = jieba.cut(data)
        all_content.extend(words)  # 从文件内容中获取文本并将结果追加到总列表


# 读取单个文件
# with open('../result.txt', encoding='utf-8') as f:  # 打开新的文本
#     data = f.read()  # 读取文本数据
# text = data
# words = jieba.cut(text)

# 去停词
stop_words_file = "E:/python练习文件/停用词/hit_stopwords.txt"
stopwords = get_custom_stopwords(stop_words_file)
words_ls = [i for i in all_content if i not in stopwords] # 将不在去除词列表中的词添加到列表中
# words_ls = list(set(words).difference(set(stopwords)))

for x in words_ls:
    print(x)

# 构造词典:分词列表转字典
dictionary = corpora.Dictionary([words_ls])
print('{:*^60}'.format('token和word mapping预览:'))
for i, w in list(dictionary.items())[:5]:  # 循环读出字典前5条的每个key和value,对应的是索引值和分词
    print('token:%s -- word:%s' % (i, w))

# 生成语料库
corpus = [dictionary.doc2bow([words]) for words in words_ls]
print('{:*^60}'.format('bag of words review:'))# 打印输出第一条语料库
print(corpus[0])

# 设置主题的个数
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=3)

# 打印所有主题,每个主题显示5个词
for topic in lda.print_topics(num_words=5):
    print(topic)

# 主题推断
print('{:*^60}'.format('主题推断'))
print(lda.inference(corpus))

遇到的问题

doc2bow expects an array of unicode tokens on input, not a single string
翻译过来就是:doc2bow希望输入一个Unicode的数组输入,不是单独的字符串,首先是参考了stackoverflow代码
所以将dictionary = corpora.Dictionary(words_ls)修改成dictionary = corpora.Dictionary([words_ls])就解决了问题。

参考书目

《Python数据分析与数据化运营》宋天龙
太喜欢作者一点点分析代码的方式了~ヾ(≧▽≦*)o

你可能感兴趣的:(机器学习,python,LDA,主题模型)