Python之酒店评论主题提取LDA主题模型

1.LDA主题模型简介

主题模型的核心思想是——一篇文章中的每个词语都是经历以下两个步骤之后生成而来

  • 一篇文章以一定概率选择了某个主题,
  • 然后并从这个主题中以一定概率选择某个词语。

p( 词语| 文档)=\sum_{主题} p(词语|主题) p( 主题 |文档 )
如下图所示:
p( 主题 |文档 )

比如某一篇文档 d,它的主题分布如右方红色柱状图所示。这篇文档最有可能是一篇体育,新闻类型的文档。
p(词语|主题) :

所以主题模型本质上想说一篇文章是如何诞生的:
1.首先选择好文章的主题 ,
2 .然后选择好符合主题的词语组合一下。
有没有发现主题模型的简单粗暴,它行文时并没有考虑词语之间的衔接,语法是否通顺等。其实主题模型依旧是一个词袋模型,并没有考虑语序,语法,语义等高级特征。不过并不妨碍它能够带给我们很多惊喜。
2.利用gensim包进行LDA实战
(1)最简单的入门案例
from gensim import corpora, models
import jieba.posseg as jp, jieba
# 文本集
texts = [
    '美国教练坦言,没输给中国女排,是输给了郎平',
    '美国无缘四强,听听主教练的评价',
    '中国女排晋级世锦赛四强,全面解析主教练郎平的执教艺术',
    '为什么越来越多的人买MPV,而放弃SUV?跑一趟长途就知道了',
    '跑了长途才知道,SUV和轿车之间的差距',
    '家用的轿车买什么好']
# 分词过滤条件
jieba.add_word('四强', 9, 'n')
flags = ('n', 'nr', 'ns', 'nt', 'eng', 'v', 'd')  # 词性
stopwords = ('', '', '知道', '', '', '听听', '坦言', '全面', '越来越', '评价', '放弃', '')  # 停词
# 分词
words_ls = []
for text in texts:
    words = [w.word for w in jp.cut(text) if w.flag in flags and w.word not in stopwords]
    words_ls.append(words)

print(words_ls)
dictionary = corpora.Dictionary(words_ls)
# 基于词典,使【词】→【稀疏向量】,并将向量放入列表,形成【稀疏向量集】
corpus = [dictionary.doc2bow(words) for words in words_ls]
print(corpus)
# lda模型,num_topics设置主题的个数
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=2)
# 打印所有主题,每个主题显示5个词
for topic in lda.print_topics(num_words=5):
    print(topic)
# 主题推断
print(lda.inference(corpus))
控制台输出:
D:\softwaretools\anaconda\python.exe D:/pycharmprojects/hoteltest01/hoteltest01/review_LDA.py
D:\softwaretools\anaconda\lib\site-packages\gensim\utils.py:1197: UserWarning: detected Windows; aliasing chunkize to chunkize_serial
  warnings.warn("detected Windows; aliasing chunkize to chunkize_serial")
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\lucky\AppData\Local\Temp\jieba.cache
Loading model cost 0.621 seconds.
Prefix dict has been built succesfully.
[['美国', '输给', '中国女排', '输给', '郎平'], ['美国', '无缘', '四强', '主教练'], ['中国女排', '晋级', '世锦赛', '四强', '主教练', '郎平', '执教', '艺术'], ['', 'MPV', 'SUV', '', '长途'], ['', '长途', 'SUV', '轿车', '差距'], ['家用', '轿车', '']]
[[(0, 1), (1, 1), (2, 2), (3, 1)], [(1, 1), (4, 1), (5, 1), (6, 1)], [(0, 1), (3, 1), (4, 1), (5, 1), (7, 1), (8, 1), (9, 1), (10, 1)], [(11, 1), (12, 1), (13, 1), (14, 1), (15, 1)], [(12, 1), (14, 1), (15, 1), (16, 1), (17, 1)], [(13, 1), (17, 1), (18, 1)]]
(0, '0.082*"SUV" + 0.081*"跑" + 0.080*"长途" + 0.079*"轿车" + 0.057*"差距"')
(1, '0.090*"美国" + 0.088*"输给" + 0.078*"四强" + 0.070*"主教练" + 0.068*"郎平"')
(array([[0.59499687, 5.405003  ],
       [0.57637316, 4.423627  ],
       [5.029799  , 3.9702005 ],
       [5.3376627 , 0.6623374 ],
       [5.4332952 , 0.56670463],
       [2.2165096 , 1.7834904 ]], dtype=float32), None)

Process finished with exit code 0

(2)酒店评论

from gensim import corpora, models
words_ls = []
review_list=[]
txt_id = 1
review_split_txt_path = 'split_result_txt/split_txt_9.txt'
f = open(review_split_txt_path, 'r', encoding='utf-8') #打开分词结果的txt文件
for line in f.readlines():
    #分词结果txt文档每行是一条评论
    #这是txt一行的样式:酒店/干净/床品/采光/周边/早上/小跑/西湖/晨练/跑步/风景/景区/没/吃/早餐
    review_words = line.split("/") 
    # print(review_words)
    words_ls.append(review_words) #将列表review_words追加到列表words_ls中,当做一个元素

print(words_ls)
dictionary = corpora.Dictionary(words_ls)
# 基于词典,使【词】→【稀疏向量】,并将向量放入列表,形成【稀疏向量集】
corpus = [dictionary.doc2bow(words) for words in words_ls]
# print(corpus)
# lda模型,num_topics设置主题的个数
lda = models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=20)
# 打印所有主题,每个主题显示10个词
for topic in lda.print_topics(num_words=10):
    print(topic)

控制台输出:

(0, '0.018*"风" + 0.015*"设计" + 0.011*"酒店" + 0.011*"独特" + 0.009*"房间" + 0.009*"空调" + 0.009*"感觉" + 0.008*"年代" + 0.008*"民国" + 0.008*"送"')
(1, '0.030*"酒店\n" + 0.019*"停车场" + 0.018*"酒店" + 0.016*"早餐" + 0.016*"房间" + 0.016*"免费" + 0.015*"停车" + 0.014*"很好" + 0.013*"一家" + 0.013*"馀"')
(2, '0.024*"近" + 0.019*"房间" + 0.018*"酒店" + 0.017*"东站" + 0.015*"西湖" + 0.011*"杭州" + 0.011*"入住" + 0.011*"风格" + 0.010*"装修" + 0.010*"湖边"')
(3, '0.042*"房间" + 0.037*"闹中取静" + 0.032*"环境" + 0.030*" " + 0.027*"酒店" + 0.019*"不错" + 0.015*"很大" + 0.014*"早餐" + 0.012*"特色" + 0.011*"味道\n"')
(4, '0.013*"客厅" + 0.010*"房间" + 0.009*"说" + 0.009*"服务" + 0.009*"吃" + 0.009*"浴室" + 0.008*"历史" + 0.008*"酒店" + 0.008*"客人" + 0.007*"早饭"')
(5, '0.036*"酒店" + 0.033*"服务" + 0.017*"西湖" + 0.017*"设施" + 0.015*"近" + 0.013*"房间" + 0.012*"早餐" + 0.012*"位置" + 0.012*"地理位置" + 0.011*"人员"')
(6, '0.056*"\n" + 0.032*"酒店" + 0.028*"住" + 0.027*"很棒\n" + 0.022*"服务" + 0.022*" " + 0.016*"满意\n" + 0.014*"精品" + 0.013*"环境" + 0.012*"这家"')
(7, '0.043*"服务" + 0.042*"升级" + 0.038*"免费" + 0.036*"酒店" + 0.030*"前台" + 0.019*"不错" + 0.018*"帮" + 0.017*"房间" + 0.014*"朋友" + 0.014*" "')
(8, '0.048*"房间" + 0.043*"酒店" + 0.037*"不错" + 0.032*"干净" + 0.027*"性价比" + 0.024*"高" + 0.019*"位置" + 0.015*"设施" + 0.015*"安静" + 0.015*"舒适"')
(9, '0.031*"不错" + 0.025*"位置" + 0.024*"酒店" + 0.023*"楼下" + 0.018*"房间" + 0.013*"出行\n" + 0.013*"卫生" + 0.011*"品牌" + 0.011*"更好\n" + 0.011*"早餐"')
(10, '0.034*"太" + 0.029*"早餐" + 0.016*"房间" + 0.015*"服务" + 0.015*"酒店" + 0.014*"差" + 0.012*"西湖" + 0.011*"不错" + 0.009*"" + 0.009*"开"')
(11, '0.036*"服务" + 0.036*"酒店" + 0.034*"房间" + 0.022*"前台" + 0.021*"不错" + 0.019*"干净" + 0.018*"早餐" + 0.013*"卫生" + 0.011*"入住" + 0.010*"交通"')
(12, '0.028*"带" + 0.020*"孩子" + 0.020*"舒服\n" + 0.016*"感觉\n" + 0.016*"家庭" + 0.015*"适合" + 0.014*"完美\n" + 0.012*"酒店" + 0.009*"早餐" + 0.009*"民国"')
(13, '0.055*"下次" + 0.034*"服务" + 0.030*"酒店" + 0.030*"住\n" + 0.028*"不错" + 0.022*"房间" + 0.020*"入住\n" + 0.019*"前台" + 0.018*"入住" + 0.016*"选择\n"')
(14, '0.026*"管家" + 0.020*"早餐" + 0.016*"房间" + 0.016*"建筑" + 0.014*"酒店" + 0.009*"东站" + 0.009*"阳台" + 0.009*"近" + 0.009*"便利" + 0.009*"不错"')
(15, '0.067*"服务\n" + 0.035*"酒店" + 0.026*"不错" + 0.023*"装修" + 0.022*"前台" + 0.021*"挺" + 0.020*"风格" + 0.016*"房间" + 0.016*"喜欢\n" + 0.012*"住"')
(16, '0.060*"西湖" + 0.047*"酒店" + 0.038*"不错" + 0.033*"早餐" + 0.019*"小张" + 0.017*"杭州" + 0.016*"周边" + 0.015*"位置" + 0.013*"性价比" + 0.012*"步行"')
(17, '0.023*"地铁站" + 0.020*"酒店" + 0.019*"早餐" + 0.015*"房间" + 0.013*"服务" + 0.013*"前台" + 0.011*"带" + 0.010*"房子" + 0.010*"服务员" + 0.009*"不错"')
(18, '0.086*"不错\n" + 0.064*"酒店" + 0.039*"服务" + 0.032*"前台" + 0.028*"老" + 0.027*" " + 0.023*"早餐" + 0.021*"不错" + 0.015*"位置" + 0.013*"环境"')
(19, '0.020*"近" + 0.019*"酒店" + 0.015*"西式" + 0.014*"三层" + 0.014*"西湖" + 0.013*"走路" + 0.013*"高铁" + 0.012*"南宋" + 0.011*"御街" + 0.011*"房间"')

 参考文献:

https://blog.csdn.net/Yellow_python/article/details/83097994    Python+gensim【中文LDA】简洁模型

https://www.jianshu.com/p/f2af7b74e506       LDA主题模型——gensim实战

https://www.cnblogs.com/Luv-GEM/p/10881838.html    文本主题抽取:用gensim训练LDA模型

 

posted @ 2020-06-27 21:38  雨后观山色  阅读(5016)  评论(0编辑  收藏  举报