侯体宗的博客
  • 首页
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

Python探索之pLSA实现代码

Python  /  管理员 发布于 7年前   203

pLSA(probabilistic Latent Semantic Analysis),概率潜在语义分析模型,是1999年Hoffman提出的一个被称为第一个能解决一词多义问题的模型,通过在文档与单词之间建立一层主题(Topic),将文档与单词的直接关联转化为文档与主题的关联以及主题与单词的关联。这里采用EM算法进行估计,可能存在差错,望积极批评指正。

# -*- coding: utf-8 -*-import mathimport randomimport jiebaimport codecsimport datetimeclass pLSA_lph():  def __init__(self, ntopic = 5):    self.n_doc = 0    self.n_word = 0    self.n_topic = ntopic    self.corpus = None    self.p_z_dw = None    self.p_w_z = None    self.p_z_d = None    self.likelihood = 0    self.vocab = None    self.stop_words = [u',', u'。', u'、', u'(', u')', u'・', u'!', u' ', u':', u'“', u'”', u'\n']  # 每行和为1的正实数,概率分布;  def _rand_mat(self, sizex, sizey):    ret = []    for i in xrange(sizex):      ret.append([])      for _ in xrange(sizey):        ret[-1].append(random.random())      norm = sum(ret[-1])      for j in xrange(sizey):        ret[-1][j] /= norm    return ret  #从文本中计算词频稀疏矩阵,这里存储模型仿照LDA  def loadCorpus(self, fn):    # 中文分词    f = open(fn, 'r')    text = f.readlines()    text = r' '.join(text)    seg_generator = jieba.cut(text)    seg_list = [i for i in seg_generator if i not in self.stop_words]    seg_list = r' '.join(seg_list)    # 切割统计所有出现的词纳入词典    seglist = seg_list.split(" ")    self.vocab = []    for word in seglist:      if (word != u' ' and word not in self.vocab):        self.vocab.append(word)    self.n_word =len(self.vocab)    CountMatrix = []    f.seek(0, 0)    # 统计每个文档中出现的词频    for line in f:      # 置零      count = [0 for i in range(len(self.vocab))]      text = line.strip()      # 但还是要先分词      seg_generator = jieba.cut(text)      seg_list = [i for i in seg_generator if i not in self.stop_words]      seg_list = r' '.join(seg_list)      seglist = seg_list.split(" ")      # 查询词典中的词出现的词频      for word in seglist:        if word in self.vocab:          count[self.vocab.index(word)] += 1      CountMatrix.append(count)    f.close()    self.corpus = CountMatrix    self.n_doc = len(CountMatrix)    #初始化    self.p_z_d = self._rand_mat(self.n_topic, self.n_doc)    self.p_w_z = self._rand_mat(self.n_word, self.n_topic)    self.p_z_dw =[]    for k in range(self.n_topic):      self.p_z_dw.append(self._rand_mat(self.n_doc, self.n_word))  def _e_step(self):    for k in range(self.n_topic):      for d in range(self.n_doc):        for j in range(self.n_word):          _d_wz_zd = 0          for kk in range(self.n_topic):_d_wz_zd += self.p_w_z[j][kk]*self.p_z_d[kk][d]          if _d_wz_zd <= 0:_d_wz_zd = 1e-6          self.p_z_dw[k][d][j] = self.p_w_z[j][k]*self.p_z_d[k][d]/_d_wz_zd  def _m_step(self):    print "updating Pn(Wj|Zk)...\r"    for j in range(self.n_word):      for k in range(self.n_topic):        _d_dw_zdw = 0        for d in range(self.n_doc):          _d_dw_zdw += self.corpus[d][j]*self.p_z_dw[k][d][j]        _d_dw_zdw_sum = 0        for jj in range(self.n_word):          _d_dw_zdw_i = 0          for d in range(self.n_doc):_d_dw_zdw_i += self.corpus[d][jj]*self.p_z_dw[k][d][jj]          _d_dw_zdw_sum += _d_dw_zdw_i        if _d_dw_zdw_sum <= 0:          _d_dw_zdw_sum = 1e-6        self.p_w_z[j][k] = _d_dw_zdw/_d_dw_zdw_sum    print "updating Pn(Zk|Di)...\r"    for k in range(self.n_topic):      for d in range(self.n_doc):        _d_dw_zdw = 0        for j in range(self.n_word):          _d_dw_zdw += self.corpus[d][j]*self.p_z_dw[k][d][j]        _d_dw_zdw_sum = 0        for kk in range(self.n_topic):          _d_dw_zdw_i = 0          for j in range(self.n_word):_d_dw_zdw_i += self.corpus[d][j]*self.p_z_dw[kk][d][j]          _d_dw_zdw_sum += _d_dw_zdw_i        if _d_dw_zdw_sum <= 0:          _d_dw_zdw_sum = 1e-6        self.p_z_d[k][d] = _d_dw_zdw/_d_dw_zdw_sum  #计算最大似然值  def _cal_max_likelihood(self):    self.likelihood = 0    for d in range(self.n_doc):      for j in range(self.n_word):        _dP_wjdi = 0        for k in range(self.n_topic):          _dP_wjdi += self.p_w_z[j][k]*self.p_z_d[k][d]        _dP_wjdi = 1.0/self.n_doc*_dP_wjdi        self.likelihood += self.corpus[d][j]*math.log(_dP_wjdi)  #迭代训练  def train(self, n_iter = 100, d_delta = 1e-6,log_fn = "log.log"):    itr = 0    delta =10e9    _likelihood = 0    f = open(log_fn, 'w')    while itr < n_iter and delta > d_delta:      _likelihood = self.likelihood      self._e_step()      self._m_step()      self._cal_max_likelihood()      itr += 1      delta = abs(self.likelihood - _likelihood)      t1 = datetime.datetime.now().strftime('%Y-%m-%d-%y %H:%M:%S');      f.write("%s iteration %d, max-likelihood = %.6f\n"%(t1, itr, self.likelihood))      print "%s iteration %d, max-likelihood = %.6f"%(t1, itr, self.likelihood)    f.close()  def printVocabulary(self):    print "vocabulary:"    for word in self.vocab:      print word,    print  def saveVocabulary(self, fn):    f = codecs.open(fn, 'w', 'utf-8')    for word in self.vocab:      f.write("%s\n"%word)    f.close()  def printWordOfTopic(self):    for k in range(self.n_topic):      print "Topic %d"%k,      for j in range(self.n_word):        print self.p_w_z[j][k],      print  def saveWordOfTopic(self,fn):    f = open(fn, 'w')    for j in range(self.n_word):      f.write(", w%d"%j)    f.write("\n")    for k in range(self.n_topic):      f.write("topic %d"%k)      for j in range(self.n_word):        f.write(", %.6f"%self.p_w_z[j][k])      f.write("\n")    f.close()  def printTopicOfDoc(self):    for d in range(self.n_doc):      print "Doc %d"%d,      for k in range(self.n_topic):        print self.p_z_d[k][d],      print  def saveTopicOfDoc(self, fn):    f = open(fn, 'w')    for k in range(self.n_topic):      f.write(", z%d" % k)    f.write("\n")    for d in range(self.n_doc):      f.write("doc %d" % d)      for k in range(self.n_topic):        f.write(", %.6f" % self.p_z_d[k][d])      f.write("\n")    f.close()

依旧采用上一篇文章中的两个政治新闻作为语料库:

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">新华社北京11月26日电中共中央总书记、国家主席习近平26日向古巴共产党中央委员会第一书记、国务委员会主席兼部长会议主席劳尔・卡斯特罗致唁电,代表中国党、政府、人民并以个人名义,对菲德尔・卡斯特罗同志逝世表示最沉痛的哀悼,向其家属致以最诚挚的慰问。全文如下:惊悉古巴革命领导人菲德尔・卡斯特罗同志不幸逝世,我谨代表中国共产党、政府、人民,并以我个人的名义,向你并通过你向古巴共产党、政府、人民,对菲德尔・卡斯特罗同志的逝世表示最沉痛的哀悼,向其家属致以最诚挚的慰问。菲德尔・卡斯特罗同志是古巴共产党和古巴社会主义事业的缔造者,是古巴人民的伟大领袖。他把毕生精力献给了古巴人民争取民族解放、维护国家主权、建设社会主义的壮丽事业,为古巴人民建立了不朽的历史功勋,也为世界社会主义发展建立了不朽的历史功勋。菲德尔・卡斯特罗同志是我们这个时代的伟大人物,历史和人民将记住他。我多次同菲德尔・卡斯特罗同志见面,促膝畅谈,他的真知灼见令我深受启发,他的音容笑貌犹在眼前。我深深怀念他,中国人民深深怀念他。菲德尔・卡斯特罗同志生前致力于中古友好,密切关注和高度评价中国发展进程,在他亲自关心和支持下,古巴成为第一个同新中国建交的拉美国家。建交56年来,中古关系长足发展,各领域务实合作成果丰硕,两国人民友谊与日俱增,这都与菲德尔・卡斯特罗同志的关怀和心血密不可分。菲德尔・卡斯特罗同志的逝世是古巴和拉美人民的重大损失,不仅使古巴和拉美人民失去了一位优秀儿子,也使中国人民失去了一位亲密的同志和真诚的朋友。他的光辉形象和伟大业绩将永载史册。我相信,在主席同志坚强领导下,古巴党、政府、人民必将继承菲德尔・卡斯特罗同志的遗志,化悲痛为力量,在社会主义建设事业中不断取得新的成绩。中古两党、两国、两国人民友谊必将得到巩固和发展。伟大的菲德尔・卡斯特罗同志永垂不朽!(完)</span> 

据韩联社报道,当地时间29日下午2时30分,韩国总统朴槿惠发表“亲信门”事件后的第3次对国民谈话。据报道,朴槿惠在谈话中表示,“我没有管理好周围的人,导致出现了一些失误。这次事件的过程将尽快向大家说明具体情况。”朴槿惠表示,之前因考虑到国内外各种困难,为了国家和人民,如何才是正确的选择,每晚都辗转反侧,难以入睡。朴槿惠指出,将把总统任期相关问题交给国会和朝野两党决定,将遵守相应规定,辞去总统职务,放下一切。朴槿惠表示,希望韩国尽快摆脱混乱局面,步入正轨。并再次向国民衷心表示道歉。希望两党能尽快齐心协力,解决当前局面,此前,在“亲信门”事件曝光后,朴槿惠曾分别于10月25日和11月4日两次发表讲话,向民众表示歉意。10月25日在青瓦台发表对国民谈话时,朴槿惠承认大选时及就任总统后曾就部分资料征求过亲信崔顺实意见,并就此事向全体国民道歉。11月4日上午,朴槿惠在青瓦台召开记者招待会,就亲信干政事件发表第二次对国民讲话, 称愿意接受特别检察组的调查。韩联社称,依据宪法享有刑事检控豁免特权的在任总统表明接受检方调查的立场,为韩国68年宪政史所仅见。

主函数入口:

if __name__=="__main__":  _plsa = pLSA_lph(2)  _plsa.loadCorpus(u"C:\\Users\Administrator\Desktop\\zhongwen.txt")  _plsa.train()  _plsa.printTopicOfDoc()  _plsa.printWordOfTopic()  _plsa.saveTopicOfDoc(u"C:\\Users\Administrator\Desktop\\topic_doc.txt")  _plsa.saveWordOfTopic(u"C:\\Users\Administrator\Desktop\\word_topic.txt")

输出每个文档中的主题分布如下:

Doc 0 0.999999999627 3.72945076781e-10
Doc 1 3.52196229806e-11 0.999999999965

总结

以上就是本文关于Python探索之pLSA实现代码的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:python正则表达式re之compile函数解析、python+mongodb数据抓取详细介绍、Python_LDA实现方法详解等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!


  • 上一条:
    python编程之requests在网络请求中添加cookies参数方法详解
    下一条:
    python正则表达式re之compile函数解析
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在python语言中Flask框架的学习及简单功能示例(0个评论)
    • 在Python语言中实现GUI全屏倒计时代码示例(0个评论)
    • Python + zipfile库实现zip文件解压自动化脚本示例(0个评论)
    • python爬虫BeautifulSoup快速抓取网站图片(1个评论)
    • vscode 配置 python3开发环境的方法(0个评论)
    • 近期文章
    • 在windows10中升级go版本至1.24后LiteIDE的Ctrl+左击无法跳转问题解决方案(0个评论)
    • 智能合约Solidity学习CryptoZombie第四课:僵尸作战系统(0个评论)
    • 智能合约Solidity学习CryptoZombie第三课:组建僵尸军队(高级Solidity理论)(0个评论)
    • 智能合约Solidity学习CryptoZombie第二课:让你的僵尸猎食(0个评论)
    • 智能合约Solidity学习CryptoZombie第一课:生成一只你的僵尸(0个评论)
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(95个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2016-11
    • 2018-04
    • 2020-03
    • 2020-04
    • 2020-05
    • 2020-06
    • 2022-01
    • 2023-07
    • 2023-10
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客