使用python的gensim做主题模型分析(LDA模型)

浏览: 14526

由于本人水平有限,对LDA的模型介绍可能不够深入或者有误之处还请各位指出,在下谢谢了;

在传统的主题挖掘中,我们可以最早的发现是使用文本聚类的算法,聚类的结果可能近似的认为满足一个主题,但是,这种基于聚类是算法普遍依赖文本之间的距离计算;而这种距离的量化在海量的文本中是难以定义的,在聚类的结果上也只是起到了区分类别的作用,并没有给语义上的信息;

主题模型是基于概率模型的主题挖掘算法,是一种使用概率的产生式模型来挖掘文本主题的新方法,在模型的假设中,主题可以根据一定的规则生成单词,那么在已经知道文本单词情况下,可以通过概率方法反推出文本集的主题分布情况;

接下来我们就开始进行用Python进行实操,从获取语料开始到得出模型的结果;这个数据集接着我的前两篇的数据一样,这个数据是未分词的训练集,这些是各个的类别目录,

Clipboard Image.png

接下来就是我们展示的文本,这个文本

Clipboard Image.png

接下来就是我们的代码部分,首先是导入我们想要的模块,也是坑爹,使用Pycharm的童鞋最好不要乱给自己的Python file 乱取名字,尔康我吃过苦头,重装了好几次pycharm 才知道是命名的冲突

# -*- coding: UTF-8 -*-
import sys
import os
import jieba
from mpltools import style
import numpy as np
from mpltools import style
import matplotlib.pyplot as plt
from gensim import corpora, models, similarities

这时候我们要设置一下我们的中文环境,这些代码这几篇文章都高度类似

# 设置中文环境#
reload(sys)
sys.setdefaultencoding("utf-8")

然后在写函数,一个读度文本的函数,一个读入停用词函数

#去除体用词
def get_stop_words(file_name):
with open(file_name,'r') as file:
return set([line.strip() for line in file])

# 度文本
def readfile(path):
fp = open(path, "rb")
content = fp.read()
fp.close()
return content

设置一下我们的路径,一个训练文本路径,一个是停用词的路径,在这里感谢一下数据集提供者,复旦的某位大神收集,虽然我也不知道名字,这有点尴尬;

corpus_path = r"E:\python_txt\answer\train/"      # 未分词分类语料
stop_file_path=r"E:\python_txt/stoplist.txt"

这就是我们停用词的样子,这里注意,我在自己的电脑上测试的停用词一直不管用,后面慢慢想是不是和编码有关,果然,和你本地的编码有关系,这里我们设置文本的编码格式utf-8

Clipboard Image.png

这里开始分词的程序

#获取每个目录下的所有文件
catelist = os.listdir(corpus_path)
print catelist
# 读入停用词目录
stop_words=get_stop_words(stop_file_path)
#设置一下我们要存入分词后列表变量
train_set=[]
for mydir in catelist:
class_path = corpus_path + mydir + '/' # 拼出未分词的目录
print class_path
file_list = os.listdir(class_path) # 获取类别目录下的所有文件
print file_list
for file_path in file_list:
full_name = class_path + file_path#
print full_name
content = readfile(full_name).strip()
content == content.replace("'\r\n'", '').replace(""'()'"",'').strip() # 删除掉换行和多于的空格
content_seg=list(jieba.cut(content, cut_all=False))
train_set.append([item for item in content_seg if str(item) not in stop_words])#剔除停用词
print "分词结束"

结果如下,这说明我们的分词已经结束了

Clipboard Image.png

接下来就是模型构建的步骤了,首先构建词频矩阵

dic = corpora.Dictionary(train_set)
corpus = [dic.doc2bow(text) for text in train_set]

构建模型,这里的参数num_topics是你想设置的主题数多少,alpha参数就是主题密度,值越大表示文档中包含更多的主题,这里的默认是1/len(corpus)


tfidf = models.TfidfModel(corpus)
corpus_tfidf = tfidf[corpus]
lda = models.LdaModel(corpus_tfidf, id2word = dic, num_topics = 100,alpha=1)
corpus_lda = lda[corpus_tfidf]

这里我们打印一下前十名的主题规则,就是一些词的组合

Clipboard Image.png

看到第一个主题规则,我们肯定能猜想是和历史有关,其他或多或少都和电子计算机有关,这些都印证我们上面的目录分类

#画图
thetas=[lda[c] for c in corpus_tfidf]
plt.hist([len(t) for t in thetas], np.arange(100))
plt.ylabel('Nr of documents')
plt.xlabel('Nr of topics')
plt.show()

Clipboard Image.png

这个图上看,我们大概可以知道,主题数在10左右的文档有100个,大多数文档的主题都在7-16,如果把刻度分细或许可以了估计了;这篇文章就说到这里

推荐 1
本文由 夏尔康 创作,采用 知识共享署名-相同方式共享 3.0 中国大陆许可协议 进行许可。
转载、引用前需联系作者,并署名作者且注明文章出处。
本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责。本站是一个个人学习交流的平台,并不用于任何商业目的,如果有任何问题,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

4 个评论

你好,我用你的数据集测试了一下没有运行成功,总是显示错误,运行到这一句就不行了,
print class_path
file_list = os.listdir(class_path)
有语料的链接么
老铁你的代码是Python2跑的吧,到3里面疯狂报错,比较蛋疼的是删除换行和空格那个地方显示需要byte这个数据类型,你这个是string,咋整啊
确实是用2.7跑的,忘记说明环境了

要回复文章请先登录注册