主题模型LDA

主题模型,说实话之前学的时候还真没见过,所以看到这一章的时候感觉很是疑惑,不知道主题模型是要干什么。看完后感觉这个主题模型应该是nlp中的一种特殊的聚类方式,可以通过对文档提取主题,然后根据不同的主题进行聚类的方式,他首先肯定不是分类问题,感觉还是可以勉强归为一种聚类吧,这一章给的一个例子感觉特别好,他是将维基百科的今年文档全部拖下来进行主题提取,所以做出这个主题还是很有意义的。

数据集

第一个例子是用的美国联合通讯社(AP)的新闻报道 数据集 ,这个数据集也是一个标准数据集,他在主题模型的一些初始工作中被使用过。另一个数据集是英文版的维基百科数据集比较大,可能需要下一段时间。我们从htto://dumps.wikimedia.org 下载整个维基百科。文中的 下载链接 当然也可以用其他年份的,文中使用扩展名为.xml.bz2的文件,直接使用gensim工具建立了索引:

注意这段代码在bash中执行,而不是python的代码。

> python -m gensim.scripts.make_wiki enwiki-latest-pages-articles.xml.bz2
> wiki_en_output
>

LDA 潜在狄利克雷分配

LDA 缩写可以表示两种机器学习的方法,一种是这里的潜在狄利克雷分配(Latent Dirichlet Allocation),另一个是线性判别式分析(Linear Discriminant Analysis),前者是一种主题模型方法,后者是一种分类方法。scikit-learn中的sklearn.lda可以实现线性判别式分析,但sklearn中并没有潜在狄利克雷分配的实现。我们使用gensim包来实现潜在狄利克雷分配。使用pip可以直接进行安装。使用AP数据,示例如下:

from gensim import corpora, models, similarities
corpus = corpora.BleiCorpus('.data/ap/ap.dat','/data/ap/vocab.txt')
model = models.ldamodel.LdaModel(corpus, num_topics = 100, id2word = corpus.id2word, alpha=1.0/len(corpus)) # 构造LDA模型函数
topics = [model[c] for c in corpus]

对于model的那个构造函数的解释:alpha是一个重要的参数,较大的alpha值会导致每个文档中包含更多的主题,alpha必须是正数,通常很小,一般小于1,默认是1.0/len(corpus)。这时topics就是目前分出来的主题,主题模型是一个稀疏的模型,即便每个文档中有很多潜在主题,也只有一小部分会被用到。

对于整个维基百科的主题建立,通过上面建立索引,我们可以继续进行下面的工作。首先是引入一些程序库,并把预处理的数据读入,然后建立lDA模型:

import logging, gensim
logging.basicConfig(
format='%(asctime)s : %(levelname)s : %(message)s',
level=logging.INFO)
idword =
gensim.corpora.Dictionary.load_from_text('wiki_en_output_wordids.txt')
mm = gensim.corpora.MmCorpus('wiki_en_output_tfidf.mm')
model = gensim.models.ldamodel.LdaModel(corpus=mm,
id2word=id2word, num_topics=100, update_every=1,
chunksize=10000, passes=1)

一旦完成,你可以把结果保存到文件里,时间比较长,但他会在控制台上看到这个过程。

model.save('wiki_ida.pkl') # 保存到文件wiki_ida.pkl中
model = gensim.models.ldamodel.LdaModel.load('wiki_ida.pkl') # 从文件wiki_ida.pkl中读出结果数据

我们可以对其中的主题进行一下分析统计

topics = []
for doc in mm:
  topics.append(model[doc])

import numpy as np
lens = np.array([len(t) for t in topics])
print np.mean(lens) # 查看一下平均每个topic下有多少篇文档
print np.mean(lens <=10) # 查看一下,文档数小于10的topic所占的比例

选择主题个数

之前我们是使用的固定的主题个数(100)来进行的统计,这个数据是随意设定的,很可能跟实际并不相符。我们其实还有一些别的方法来自动的确定主题数目,有一个很流行的模型叫做层次狄利克雷过程(HDP),可以在gensim中使用。同LDA代码很相似,只需要把gensim.models.ldamodel.LdaModel的调用替换成一个对HdpModel 构造函数的调用即可,如下所示,但HDP方法计算时间要比LDA更长。

hdp = gensim.models.hdpmodel.HdpModel(mm,id2word)

猜你喜欢

转载自blog.csdn.net/northhan/article/details/51125848