【Python】LDA模型中⽂⽂本主题提取⼁可视化⼯具pyLDAvis的使⽤
主题模型LDA的实现及其可视化pyLDAvis
1. ⽆监督提取⽂档主题——LDA模型
1.1 准备⼯作
1.2 调⽤api实现模型
2. LDA的可视化交互分析——pyLDAvis
2.1 安装pyLDAvis
2.2 结合gensim调⽤api实现可视化
p.s. 保存结果为独⽴⽹页
p.p.s. 加快prepare速度?
2.3 如何分析pyLDAvis可视化结果
2.3.1. 每个主题表⽰什么意义?
2.3.2 每个主题有多么普遍?
2.3.3 主题之间有什么关联?
3. ⽆监督提取⽂档主题——LDA模型
这个模型具体介绍、应⽤场景什么的就不谈了,你知道它能从⼀堆的⽂本中给你反馈出规定主题数的词语聚类就可以了。
由于是⽆监督算法,意味着你不需要去准备训练集,不⽤去苦逼地打标签,在数据准备阶段任务量⾄少省掉了⼀半啊。
⽽作为数学⼩⽩,其中具体原理如⽆必要我⼀向是不愿深究的,只要有⼈证明可⾏,那我拿来就⽤。聪明的脑袋要各尽其⽤嘛(笑
但也许我之后始终逃不掉要学习原理吧,先把原理解释放在这⾥,之后需要时再看。
故⽽本篇主要介绍的是如何上⼿实现及如何分析结果,这才是Data Scientist该⼲的事嘛
1. ⽆监督提取⽂档主题——LDA模型
1.1 准备⼯作
书归正传。以本次⼯作为例,我需要分析爬取到500名⽤户每⼈50页微博,⼤概500* 50* 10=250000条微博⽂本的主题情况。也就是说想看看这些⼈的微博主要是在关⼼些什么,他们共同关注哪些⽅⾯。
编程环境:
python 3.6 + pycharm 2018,
LDA实现使⽤的包是gensim,
分词还是⽤我们的⽼朋朋朋朋友jieba.
数据准备:
爬到的原始数据存在csv中,我想的是将所有的微博⽂本分⾏读到⼀个txt中,然后分词去停⽤词,就达到gensim的输⼊标准了。
分词前:
分词后:
【code】
⽤于处理原始⽂本。
def stopwordslist(filepath):
stopwords =[line.strip()for line in open(filepath,'r', encoding='utf-8').readlines()]
return stopwords
# 对句⼦进⾏分词
def seg_sentence(sentence):
sentence = re.sub(u'[0-9\.]+', u'', sentence)
jb.add_word('光线摄影学院')# 这⾥是加⼊⽤户⾃定义的词来补充jieba词典。
jb.add_word('曾兰⽼师')# 同样,如果你想删除哪个特定的未登录词,就先把它加上然后放进停⽤词表⾥。 jb.add_word('⽹页链接')
jb.add_word('微博视频')
jb.add_word('发布了头条⽂章')
jb.add_word('青春有你')
jb.add_word('青你')
sentence_seged = jb.cut(sentence.strip())
stopwords = stopwordslist('')# 这⾥加载停⽤词的路径
outstr =''
for word in sentence_seged:
if word not in stopwords and word.__len__()>1:
if word !='\t':
outstr += word
outstr +=" "
return outstr
inputs =open('input/like_mi10_user_','r', encoding='utf-8')
outputs =open('output1/mi10_user_','w',encoding='utf-8')
for line in inputs:
line_seg = seg_sentence(line)# 这⾥的返回值是字符串
outputs.write(line_seg +'\n')
outputs.close()
inputs.close()
1.2 调⽤api实现模型
准备数据两⼩时,接⼝调⽤三分钟,等待结果两⼩时。
gensim很友好,词典、词袋模型、lda模型都是⼀句话搞定。
【code】
from gensim import corpora
dels import LdaModel
pora import Dictionary
train =[]
fp = codecs.open('output1/mi10_user_','r',encoding='utf8')
for line in fp:
if line !='':
line = line.split()
train.append([w for w in line])
dictionary = corpora.Dictionary(train)
corpus =[dictionary.doc2bow(text)for text in train]
lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=20, passes=60) # num_topics:主题数⽬
# passes:训练伦次
# num_words:每个主题下输出的term的数⽬
for topic in lda.print_topics(num_words =20):
termNumber = topic[0]
print(topic[0],':', sep='')
listOfTerms = topic[1].split('+')
for term in listOfTerms:
listItems = term.split('*')
print(' ', listItems[1],'(', listItems[0],')', sep='')
最后的输出是
0:
"北京"(0.024)
"疫情"(0.021)
"中国联通"(0.019)
"领券"(0.019)
"购物"(0.016)
"新冠"(0.016)
"专享"(0.012)
"元券"(0.012)
"确诊"(0.012)
"上海"(0.011)
"优惠"(0.011)
"肺炎"(0.010)
"新闻"(0.010)
"病例"(0.010)
"汽车"(0.009)
1:
"⼩⽶"(0.133)
"Redmi"(0.019)
"新浪"(0.019)
"智慧"(0.018)
"雷军"(0.014)
"众测"(0.012)
"体验"(0.012)
"智能"(0.012)
"MIUI"(0.012)
"电视"(0.012)
"红⽶"(0.011)
"空调"(0.009)
"产品"(0.009)
"品牌"(0.009)
"价格"(0.008)
2:
"抽奖"(0.056)
"平台"(0.032)
"评测"(0.022)
"⽣活"(0.013)
"红包"(0.013)
"关注"(0.012)
"这条"(0.012)
"视频"(0.012)
"⼯具"(0.011)
"获得"(0.011)
"有效"(0.011)
"进⾏"(0.010)
python中文文档"恭喜"(0.010)
"⽤户"(0.010)
"公正"(0.010)
.....
这种。他只会返回给你规定主题数下的多少词,每个词后⾯的⼩数可认为是这个词属于这个主题的概率,主题下所有词的概率和为1;⽽这个主题应该是什么,就要靠你⼈⼯后⾯分析来定义了。
那,盯着这⼀堆冷冰冰的词语和数字,也许你能通过概率衡量出这个词和这个主题的关系,但你能看出不同主题之间的关系吗?你能看出⼀个词和其他主题的关系吗?
有点困难。这时就要引出我们的LDA可视化分析⼯具了。
2. LDA的可视化交互分析——pyLDAvis
先上效果图:
2.1 安装pyLDAvis
pip install pyldavis
2.2 结合gensim调⽤api实现可视化
pyLDAvis⽀持三种包内lda模型的直接传⼊:sklearn、gensim、graphlab,好像也可以⾃⼰算。这⾥当然紧接上⽂直接⽤gensim得到的lda模型了。
pyLDAvis也很友好,同样⼀句话完成实现:
sim
'''插⼊之前的代码⽚段'''
sim.prepare(lda, corpus, dictionary)
'''
lda: 计算好的话题模型
corpus: ⽂档词频矩阵
dictionary: 词语空间
'''
pyLDAvis.show(d)#展⽰在浏览器
# pyLDAvis.displace(d) #展⽰在notebook的output cell中
数据量很⼤,运⾏时间稍长。
p.s. 保存结果为独⽴⽹页
同时,如果你希望能够将这个结果保存为独⽴⽹页以便分享或放到web系统中,那么可以这样
sim.prepare(lda, corpus, dictionary)
pyLDAvis.save_html(d,'lda_pass10.html')# 将结果保存为该html⽂件
就不⽤每次都等好久时间跑结果了。。
p.p.s. 加快prepare速度?
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论