设为首页 收藏本站
查看: 10408|回复: 0

[经验分享] 用python计算lda语言模型的困惑度并作图

[复制链接]

尚未签到

发表于 2015-4-23 09:23:31 | 显示全部楼层 |阅读模式
  转载请注明:电子科技大学EClab——落叶花开http://www.iyunv.com/nlp-yekai/p/3816532.html
  困惑度一般在自然语言处理中用来衡量训练出的语言模型的好坏。在用LDA做主题和词聚类时,原作者D.Blei就是采用了困惑度来确定主题数量。文章中的公式为:
  perplexity=exp^{ - (∑log(p(w))) / (N) }
  其中,P(W)是指的测试集中出现的每一个词的概率,具体到LDA的模型中就是P(w)=∑z p(z|d)*p(w|z)【z,d分别指训练过的主题和测试集的各篇文档】。分母的N是测试集中出现的所有词,或者说是测试集的总长度,不排重。
  因而python程序代码块需要包括几个方面:
  1.对训练的LDA模型,将Topic-word分布文档转换成字典,方便查询概率,即计算perplexity的分子
  2.统计测试集长度,即计算perplexity的分母
  3.计算困惑度
  4.对于不同的Topic数量的模型,计算的困惑度,画折线图。
  python代码如下:
  



1 # -*- coding: UTF-8-*-
2 import numpy
3 import math
4 import string
5 import matplotlib.pyplot as plt
6 import re
7
8 def dictionary_found(wordlist):               #对模型训练出来的词转换成一个词为KEY,概率为值的字典。
9     word_dictionary1={}
10     for i in xrange(len(wordlist)):
11         if i%2==0:
12             if word_dictionary1.has_key(wordlist)==True:
13                 word_probability=word_dictionary1.get(wordlist)
14                 word_probability=float(word_probability)+float(wordlist[i+1])
15                 word_dictionary1.update({wordlist:word_probability})
16             else:
17                 word_dictionary1.update({wordlist:wordlist[i+1]})
18         else:
19             pass
20     return word_dictionary1
21
22 def look_into_dic(dictionary,testset):          #对于测试集的每一个词,在字典中查找其概率。
23     '''Calculates the TF-list for perplexity'''   
24     frequency=[]
25     letter_list=[]
26     a=0.0
27     for letter in testset.split():
28         if letter not in letter_list:
29             letter_list.append(letter)
30             letter_frequency=(dictionary.get(letter))
31             frequency.append(letter_frequency)
32         else:
33             pass
34     for each in frequency:
35         if each!=None:
36             a+=float(each)
37         else:
38             pass
39     return a
40
41
42 def f_testset_word_count(testset):                                     #测试集的词数统计
43     '''reture the sum of words in testset which is the denominator of the formula of Perplexity'''
44     testset_clean=testset.split()
45     return (len(testset_clean)-testset.count("\n"))
46
47 def f_perplexity(word_frequency,word_count):             #计算困惑度
48     '''Search the probability of each word in dictionary
49     Calculates the perplexity of the LDA model for every parameter T'''
50     duishu=-math.log(word_frequency)
51     kuohaoli=duishu/word_count
52     perplexity=math.exp(kuohaoli)
53     return perplexity
54
55 def graph_draw(topic,perplexity):             #做主题数与困惑度的折线图
56     x=topic
57     y=perplexity
58     plt.plot(x,y,color="red",linewidth=2)
59     plt.xlabel("Number of Topic")
60     plt.ylabel("Perplexity")
61     plt.show()
62
63
64 topic=[]
65 perplexity_list=[]
66 f1=open('/home/alber/lda/GibbsLDA/jd/test.txt','r')      #测试集目录
67 testset=f1.read()
68 testset_word_count=f_testset_word_count(testset)         #call the function to count the sum-words in testset
69 for i in xrange(14):
70     dictionary={}
71     topic.append(5*(3i+1))                                                       #模型文件名的迭代公式
72     trace="/home/alber/lda/GibbsLDA/jd/stats/model-final-"+str(5*(i+1))+".txt"   #模型目录
73     f=open(trace,'r')
74     text=f.readlines()
75     word_list=[]
76     for line in text:
77         if "Topic" not in line:
78             line_clean=line.split()
79             word_list.extend(line_clean)   
80         else:
81             pass
82     word_dictionary=dictionary_found(word_list)
83     frequency=look_into_dic(word_dictionary,testset)      
84     perplexity=f_perplexity(frequency,testset_word_count)      
85     perplexity_list.append(perplexity)        
86 graph_draw(topic,perplexity_list)
  下面是画出的折线图,在拐点附近再调整参数(当然与测试集有关,有图为证~~),寻找最优的主题数。实验证明,只要Topic选取数量在其附近,主题抽取一般比较理想。
DSC0000.png DSC0001.png
  
  
  本人也是新手开始作研究~程序或者其他地方有错误的,希望大家指正。
  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59890-1-1.html 上篇帖子: python 科学计算(一) 下篇帖子: Python Decorators Overview
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表