LDA

[python] LDA处理文档主题分布代码入门笔记

标签: LDApython主题分布入门介绍代码分析

2016-03-09 03:23 9905人阅读 评论(9) 收藏 举报

 分类:

机器学习(20)  知识图谱(14) 

版权声明:本文为博主原创文章,转载请注明CSDN博客源地址!共同学习,一起进步~

目录(?)[+]

以前只知道LDA是个好东西,但自己并没有真正去使用过。同时,关于它的文章也非常之多,推荐大家阅读书籍《LDA漫游指南》,最近自己在学习文档主题分布和实体对齐中也尝试使用LDA进行简单的实验。这篇文章主要是讲述Python下LDA的基础用法,希望对大家有所帮助。如果文章中有错误或不足之处,还请海涵~

一. 下载安装

LDA推荐下载地址包括:其中前三个比较常用。
        gensim下载地址:https://radimrehurek.com/gensim/models/ldamodel.html
        pip install lda安装地址:https://github.com/ariddell/lda
        scikit-learn官网文档:LatentDirichletAllocation
其中sklearn的代码例子可参考下面这篇:
        Topic extraction with NMF and Latent Dirichlet Allocation
其部分输出如下所示,包括各个主体Topic包含的主题词:

[plain] view plain copy

  1. Loading dataset...
  2. Fitting LDA models with tf features, n_samples=2000 and n_features=1000...
  3. done in 0.733s.
  4. Topics in LDA model:
  5. Topic #0:
  6. 000 war list people sure civil lot wonder say religion america accepted punishment bobby add liberty person kill concept wrong
  7. Topic #1:
  8. just reliable gods consider required didn war makes little seen faith default various civil motto sense currency knowledge belief god
  9. Topic #2:
  10. god omnipotence power mean rules omnipotent deletion policy non nature suppose definition given able goal nation add place powerful leaders
  11. ....

下面这三个也不错,大家有时间的可以见到看看:
        https://github.com/arongdari/python-topic-model
        https://github.com/shuyo/iir/tree/master/lda
        https://github.com/a55509432/python-LDA
其中第三个作者a55509432的我也尝试用过,模型输出文件为:

model_parameter.dat 保存模型训练时选择的参数
wordidmap.dat 保存词与id的对应关系,主要用作topN时查询
model_twords.dat 输出每个类高频词topN个
model_tassgin.dat 输出文章中每个词分派的结果,文本格式为词id:类id
model_theta.dat 输出文章与类的分布概率,文本一行表示一篇文章,概率1 概率2..表示文章属于类的概率
model_phi.dat 输出词与类的分布概率,是一个K*M的矩阵,K为设置分类的个数,M为所有文章的词的总数

但是短文本信息还行,但使用大量文本内容时,输出文章与类分布概率几乎每行数据存在大量相同的,可能代码还存在BUG。

下面是介绍使用pip install lda安装过程及代码应用:

[python] view plain copy

  1. pip install lda

参考:[python] 安装numpy+scipy+matlotlib+scikit-learn及问题解决

二. 官方文档

这部分内容主要参考下面几个链接,强推大家去阅读与学习:
        官网文档:https://github.com/ariddell/lda
        lda: Topic modeling with latent Dirichlet Allocation
        Getting started with Latent Dirichlet Allocation in Python - sandbox
        [翻译] 在Python中使用LDA处理文本 - letiantian
        文本分析之TFIDF/LDA/Word2vec实践 - vs412237401

1.载入数据

[python] view plain copy

  1. import numpy as np
  2. import lda
  3. import lda.datasets
  4. # document-term matrix
  5. X = lda.datasets.load_reuters()
  6. print("type(X): {}".format(type(X)))
  7. print("shape: {}\n".format(X.shape))
  8. print(X[:5, :5])
  9. # the vocab
  10. vocab = lda.datasets.load_reuters_vocab()
  11. print("type(vocab): {}".format(type(vocab)))
  12. print("len(vocab): {}\n".format(len(vocab)))
  13. print(vocab[:5])
  14. # titles for each story
  15. titles = lda.datasets.load_reuters_titles()
  16. print("type(titles): {}".format(type(titles)))
  17. print("len(titles): {}\n".format(len(titles)))
  18. print(titles[:5])

载入LDA包数据集后,输出如下所示:
X矩阵为395*4258,共395个文档,4258个单词,主要用于计算每行文档单词出现的次数(词频),然后输出X[5,5]矩阵;
vocab为具体的单词,共4258个,它对应X的一行数据,其中输出的前5个单词,X中第0列对应church,其值为词频;
titles为载入的文章标题,共395篇文章,同时输出0~4篇文章标题如下。

[python] view plain copy

  1. type(X): <type ‘numpy.ndarray‘>
  2. shape: (395L, 4258L)
  3. [[ 1  0  1  0  0]
  4. [ 7  0  2  0  0]
  5. [ 0  0  0  1 10]
  6. [ 6  0  1  0  0]
  7. [ 0  0  0  2 14]]
  8. type(vocab): <type ‘tuple‘>
  9. len(vocab): 4258
  10. (‘church‘, ‘pope‘, ‘years‘, ‘people‘, ‘mother‘)
  11. type(titles): <type ‘tuple‘>
  12. len(titles): 395
  13. (‘0 UK: Prince Charles spearheads British royal revolution. LONDON 1996-08-20‘,
  14. ‘1 GERMANY: Historic Dresden church rising from WW2 ashes. DRESDEN, Germany 1996-08-21‘,
  15. "2 INDIA: Mother Teresa‘s condition said still unstable. CALCUTTA 1996-08-23",
  16. ‘3 UK: Palace warns British weekly over Charles pictures. LONDON 1996-08-25‘,
  17. ‘4 INDIA: Mother Teresa, slightly stronger, blesses nuns. CALCUTTA 1996-08-25‘)

From the above we can see that there are 395 news items (documents) and a vocabulary of size 4258. The document-term matrix, X, has a count of the number of occurences of each of the 4258 vocabulary words for each of the 395 documents.
下面是测试文档编号为0,单词编号为3117的数据,X[0,3117]:

[python] view plain copy

  1. # X[0,3117] is the number of times that word 3117 occurs in document 0
  2. doc_id = 0
  3. word_id = 3117
  4. print("doc id: {} word id: {}".format(doc_id, word_id))
  5. print("-- count: {}".format(X[doc_id, word_id]))
  6. print("-- word : {}".format(vocab[word_id]))
  7. print("-- doc  : {}".format(titles[doc_id]))
  8. ‘‘‘‘‘输出
  9. doc id: 0 word id: 3117
  10. -- count: 2
  11. -- word : heir-to-the-throne
  12. -- doc  : 0 UK: Prince Charles spearheads British royal revolution. LONDON 1996-08-20
  13. ‘‘‘

2.训练模型

其中设置20个主题,500次迭代

[python] view plain copy

  1. model = lda.LDA(n_topics=20, n_iter=500, random_state=1)
  2. model.fit(X)          # model.fit_transform(X) is also available

3.主题-单词(topic-word)分布

代码如下所示,计算‘church‘, ‘pope‘, ‘years‘这三个单词在各个主题(n_topocs=20,共20个主题)中的比重,同时输出前5个主题的比重和,其值均为1。

[python] view plain copy

  1. topic_word = model.topic_word_
  2. print("type(topic_word): {}".format(type(topic_word)))
  3. print("shape: {}".format(topic_word.shape))
  4. print(vocab[:3])
  5. print(topic_word[:, :3])
  6. for n in range(5):
  7. sum_pr = sum(topic_word[n,:])
  8. print("topic: {} sum: {}".format(n, sum_pr))

输出结果如下:

[python] view plain copy

  1. type(topic_word): <type ‘numpy.ndarray‘>
  2. shape: (20L, 4258L)
  3. (‘church‘, ‘pope‘, ‘years‘)
  4. [[  2.72436509e-06   2.72436509e-06   2.72708945e-03]
  5. [  2.29518860e-02   1.08771556e-06   7.83263973e-03]
  6. [  3.97404221e-03   4.96135108e-06   2.98177200e-03]
  7. [  3.27374625e-03   2.72585033e-06   2.72585033e-06]
  8. [  8.26262882e-03   8.56893407e-02   1.61980569e-06]
  9. [  1.30107788e-02   2.95632328e-06   2.95632328e-06]
  10. [  2.80145003e-06   2.80145003e-06   2.80145003e-06]
  11. [  2.42858077e-02   4.66944966e-06   4.66944966e-06]
  12. [  6.84655429e-03   1.90129250e-06   6.84655429e-03]
  13. [  3.48361655e-06   3.48361655e-06   3.48361655e-06]
  14. [  2.98781661e-03   3.31611166e-06   3.31611166e-06]
  15. [  4.27062069e-06   4.27062069e-06   4.27062069e-06]
  16. [  1.50994982e-02   1.64107142e-06   1.64107142e-06]
  17. [  7.73480150e-07   7.73480150e-07   1.70946848e-02]
  18. [  2.82280146e-06   2.82280146e-06   2.82280146e-06]
  19. [  5.15309856e-06   5.15309856e-06   4.64294180e-03]
  20. [  3.41695768e-06   3.41695768e-06   3.41695768e-06]
  21. [  3.90980357e-02   1.70316633e-03   4.42279319e-03]
  22. [  2.39373034e-06   2.39373034e-06   2.39373034e-06]
  23. [  3.32493234e-06   3.32493234e-06   3.32493234e-06]]
  24. topic: 0 sum: 1.0
  25. topic: 1 sum: 1.0
  26. topic: 2 sum: 1.0
  27. topic: 3 sum: 1.0
  28. topic: 4 sum: 1.0

4.计算各主题Top-N个单词

下面这部分代码是计算每个主题中的前5个单词

[python] view plain copy

  1. n = 5
  2. for i, topic_dist in enumerate(topic_word):
  3. topic_words = np.array(vocab)[np.argsort(topic_dist)][:-(n+1):-1]
  4. print(‘*Topic {}\n- {}‘.format(i, ‘ ‘.join(topic_words)))

输出如下所示:

[python] view plain copy

  1. *Topic 0
  2. - government british minister west group
  3. *Topic 1
  4. - church first during people political
  5. *Topic 2
  6. - elvis king wright fans presley
  7. *Topic 3
  8. - yeltsin russian russia president kremlin
  9. *Topic 4
  10. - pope vatican paul surgery pontiff
  11. *Topic 5
  12. - family police miami versace cunanan
  13. *Topic 6
  14. - south simpson born york white
  15. *Topic 7
  16. - order church mother successor since
  17. *Topic 8
  18. - charles prince diana royal queen
  19. *Topic 9
  20. - film france french against actor
  21. *Topic 10
  22. - germany german war nazi christian
  23. *Topic 11
  24. - east prize peace timor quebec
  25. *Topic 12
  26. - n‘t told life people church
  27. *Topic 13
  28. - years world time year last
  29. *Topic 14
  30. - mother teresa heart charity calcutta
  31. *Topic 15
  32. - city salonika exhibition buddhist byzantine
  33. *Topic 16
  34. - music first people tour including
  35. *Topic 17
  36. - church catholic bernardin cardinal bishop
  37. *Topic 18
  38. - harriman clinton u.s churchill paris
  39. *Topic 19
  40. - century art million museum city

5.文档-主题(Document-Topic)分布

计算输入前10篇文章最可能的Topic

[python] view plain copy

  1. doc_topic = model.doc_topic_
  2. print("type(doc_topic): {}".format(type(doc_topic)))
  3. print("shape: {}".format(doc_topic.shape))
  4. for n in range(10):
  5. topic_most_pr = doc_topic[n].argmax()
  6. print("doc: {} topic: {}".format(n, topic_most_pr))

输出如下所示:

[python] view plain copy

  1. type(doc_topic): <type ‘numpy.ndarray‘>
  2. shape: (395L, 20L)
  3. doc: 0 topic: 8
  4. doc: 1 topic: 1
  5. doc: 2 topic: 14
  6. doc: 3 topic: 8
  7. doc: 4 topic: 14
  8. doc: 5 topic: 14
  9. doc: 6 topic: 14
  10. doc: 7 topic: 14
  11. doc: 8 topic: 14
  12. doc: 9 topic: 8

6.两种作图分析

详见英文原文,包括计算各个主题中单词权重分布的情况:

[python] view plain copy

  1. import matplotlib.pyplot as plt
  2. f, ax= plt.subplots(5, 1, figsize=(8, 6), sharex=True)
  3. for i, k in enumerate([0, 5, 9, 14, 19]):
  4. ax[i].stem(topic_word[k,:], linefmt=‘b-‘,
  5. markerfmt=‘bo‘, basefmt=‘w-‘)
  6. ax[i].set_xlim(-50,4350)
  7. ax[i].set_ylim(0, 0.08)
  8. ax[i].set_ylabel("Prob")
  9. ax[i].set_title("topic {}".format(k))
  10. ax[4].set_xlabel("word")
  11. plt.tight_layout()
  12. plt.show()

输出如下图所示:

第二种作图是计算文档具体分布在那个主题,代码如下所示:

[python] view plain copy

  1. import matplotlib.pyplot as plt
  2. f, ax= plt.subplots(5, 1, figsize=(8, 6), sharex=True)
  3. for i, k in enumerate([1, 3, 4, 8, 9]):
  4. ax[i].stem(doc_topic[k,:], linefmt=‘r-‘,
  5. markerfmt=‘ro‘, basefmt=‘w-‘)
  6. ax[i].set_xlim(-1, 21)
  7. ax[i].set_ylim(0, 1)
  8. ax[i].set_ylabel("Prob")
  9. ax[i].set_title("Document {}".format(k))
  10. ax[4].set_xlabel("Topic")
  11. plt.tight_layout()
  12. plt.show()

输出结果如下图:

三. 总结

这篇文章主要是对Python下LDA用法的入门介绍,下一篇文章将结合具体的txt文本内容进行分词处理、文档主题分布计算等。其中也会涉及python计算词频tf和tfidf的方法。
由于使用fit()总报错“TypeError: Cannot cast array data from dtype(‘float64‘) to dtype(‘int64‘) according to the rule ‘safe‘”,后使用sklearn中计算词频TF方法:
http://scikit-learn.org/stable/modules/feature_extraction.html#text-feature-extraction

总之,希望文章对你有所帮助吧!尤其是刚刚接触机器学习、Sklearn、LDA的同学,毕竟我自己其实也只是一个门外汉,没有系统的学习过机器学习相关的内容,所以也非常理解那种不知道如何使用一种算法的过程,毕竟自己就是嘛,而当你熟练使用后才会觉得它非常简单,所以入门也是这篇文章的宗旨吧!
最后非常感谢上面提到的文章链接作者,感谢他们的分享。如果有不足之处,还请海涵~
(By:Eastmount 2016-03-17 深夜3点半  http://blog.csdn.net/eastmount/ )

时间: 2024-12-18 17:43:01

LDA的相关文章

【LDA】动手实现LDA

这段时间对LDA比较感兴趣,尝试在工作中使用它.平时做想法的快速验证,都用的是"GibbsLDA++-0.2",一个c实现版本的LDA.这两天用c++ stl自己写了一个单机版的LDA,初衷如下: 1. "GibbsLDA++-0.2"虽说号称是最popular的LDA工具包,不过依然有明显的bug,参考"[LDA]修正 GibbsLDA++-0.2 中的两个内存问题". 2. "GibbsLDA++-0.2"基本上使用纯c写

LDA/PCA

LDA(Linear Discriminant Analysis 线性判别分析),是一种监督学习.将带上标签的数据(点),通过投影的方法,投影到维度更低的空间中,使得投影后的点,会形成按类别区分,一簇一簇的情况,相同类别的点,将会在投影后的空间中更接近.LDA是一种线性分类器.分类的目标是,使得类别内的点距离越近越好(集中),类别间的点越远越好. PCA(主成分分析):LDA的输入数据是带标签的,而PCA的输入数据是不带标签的,所以PCA是一种无监督学习.LDA通常来说是作为一个独立的算法存在,

主题模型TopicModel:LDA中的数学模型

http://blog.csdn.net/pipisorry/article/details/42672935 了解LDA需要明白如下数学原理: 一个函数:gamma函数 四个分布:二项分布.多项分布.beta分布.Dirichlet分布 一个概念和一个理念:共轭先验和贝叶斯框架 两个模型:pLSA.LDA(文档-主题,主题-词语) 一个采样:Gibbs采样 估计未知参数所采用的不同思想:频率学派.贝叶斯学派 皮皮Blog gamma函数 Gamma函数 Γ(x)=∫∞0tx?1e?tdt 通过

线性判别分析(Linear Discriminant Analysis, LDA)算法初识

LDA算法入门 一. LDA算法概述: 线性判别式分析(Linear Discriminant Analysis, LDA),也叫做Fisher线性判别(Fisher Linear Discriminant ,FLD),是模式识别的经典算法,它是在1996年由Belhumeur引入模式识别和人工智能领域的.性鉴别分析的基本思想是将高维的模式样本投影到最佳鉴别矢量空间,以达到抽取分类信息和压缩特征空间维数的效果,投影后保证模式样本在新的子空间有最大的类间距离和最小的类内距离,即模式在该空间中有最佳

LDA算法入门

http://blog.csdn.net/warmyellow/article/details/5454943 一. LDA算法概述: 线性判别式分析(Linear Discriminant Analysis, LDA),也叫做Fisher线性判别(Fisher Linear Discriminant ,FLD),是模式识别的经典算法,它是在1996年由Belhumeur引入模式识别和人工智能领域的.性鉴别分析的基本思想是将高维的模式样本投影到最佳鉴别矢量空间,以达到抽取分类信息和压缩特征空间维

matlab 工具之各种降维方法工具包,下载及使用教程,有PCA, LDA, 等等。。。

最近跑深度学习,提出的feature是4096维的,放到我们的程序里,跑得很慢,很慢.... 于是,一怒之下,就给他降维处理了,但是matlab 自带的什么pca( ), princomp( )函数,搞不清楚怎么用的,表示不大明白,下了一个软件包: 名字:Matlab Toolbox for Dimensionality Reduction 链接:http://lvdmaaten.github.io/drtoolbox/ Currently, the Matlab Toolbox for Dim

【LDA】修正 GibbsLDA++-0.2 中的两个内存问题

周末这两天在家用LDA做个小实验.在LDA的众多实现的工具包中,GibbsLDA 是应用最广泛的,包括c++版本.java版本等.GibbsLDA++ 是它的C++版本的实现,目前最新版本是0.2版.在实际使用过程中,发现这个实现版本有内存使用问题.我花了一些时间定位到了问题,贴出来供大家参考. 问题1:数组内存访问越界 在model.cpp中,用到了两个矩阵nw和nd,分别存储word-topic关系和document-topic关系.这两个矩阵的大小分别是V * K和 M * K,其中,V是

LDA variational inference note, LDA 参数求解

1.LDA主题模型 给定先验概率参数αβ,主题混合参数θ,集合主题z,集合词w的联合分布为            (1) 2.variational inference 1>variational distribution variational inference algorithm 介绍的variational 分布:                                (3) 是作为后验概率p(θ, z, w | α, β)的代替.variational分布的参数γ和φ通过求解最

LDA and GDA

LDA 推导 Generalized Discriminant Analysis \

浅谈LDA

LDA是导师10月初布置的内容,每次拿起来<LDA数学八卦>看前面的公式推导都觉得这是个很难的问题,一直拖到10月末.这周末用了两天时间终于把LDA弄懂了,其实LDA是一个很简单的模型,不要被前面的数学公式吓到.当然,作为一个初学者,如果有什么理解不对的,欢迎大家批评指正. 和<LDA数学八卦>不同,我想先从这个模型说起. 现在我有M篇文章,这些文章由V个单词组成.每个单词可能属于不同的主题,主题总个数是K(我们并不知道每个单词是什么主题).现在要根据现有的语料得出一篇新文章的主题