gensim---LDA---perplexity

以下内容来源于https://blog.csdn.net/qq_25073545/article/details/79773807
使用gensim实现lda,并计算perplexity( gensim Perplexity Estimates in LDA Model)
Neither. The values coming out of bound() depend on the number of topics (as well as number of words), so they’re not comparable across different num_topics (or different test corpora).
从bound()中得出的值取决于主题的数量(以及单词的数量),因此它们在不同的num_topics(或不同的测试语料库)上是不可比的。
the opposite:a smaller bound value implies deterioration. For example, bound -6000 is “better” than -7000 (bigger is better
较小的界限值意味着恶化。例如,界限6000比7000更“好”,更大更好。

使用log_perplexity方法评估LDA
代码示例1

from gensim.models import LdaModel
from gensim.corpora import Dictionary
import numpy as np

docs = [["a", "a", "b"], 
        ["a", "c", "g"], 
        ["c"],
        ["a", "c", "g"]]

dct = Dictionary(docs)
corpus = [dct.doc2bow(_) for _ in docs]
c_train, c_test = corpus[:2], corpus[2:]

ldamodel = LdaModel(corpus=c_train, num_topics=2, id2word=dct)
Per-word Perplexity=ldamodel.log_perplexity(c_test)
print(Per-word Perplexity)

corpus:59000 documents
unique token:500000
我估计R中的最终模型来利用它的可视化工具来解释我的结果,但是首先我需要为我的模型选择主题的数量。因为我没有直觉关于潜在结构中有多少主题,所以我要估计一系列模型,主题k=20, 25, 30…并估计每个模型的困惑,以确定在Blei(2003)中推荐的最佳主题数目。在我知道的(LDA和TopICModels)中,用于估计LDA的唯一包使用batch LDA,每当我估计一个具有超过70个主题的模型时,我就用完了内存(这是一个超级计算集群,每个处理器的RAM多达96千兆字节)。我认为我可以使用gensim来估计一系列的模型,使用的是online LDA,它的内存强度要少得多,计算出一个保存(held-out)的文档样本的困惑,根据这些结果选择主题的数量,然后在R中使用batch LDA来估计最终模型。
步骤如下:
1.从R中的一系列文本文件生成语料库,以MM格式导出文档术语矩阵和字典。
2.在Python中导入语料库和词典。
3.将语料库分成训练/测试数据集。
4.利用训练数据估计LDA模型。
5.使用测试数据计算边界和每个字的困惑。
我的理解是困惑总是随着话题数量的增加而减少,所以最佳的话题数量应该是困惑中的边际变化小。然而,每当我估计一系列模型时,困惑实际上随着话题的数量而增加。对于k=20/25/30/35/40的困惑度的值:

Perplexity (20 topics):  -44138604.0036
Per-word Perplexity:  542.513884961
Perplexity (25 topics):  -44834368.1148
Per-word Perplexity:  599.120014719
Perplexity (30 topics):  -45627143.4341
Per-word Perplexity:  670.851965367
Perplexity (35 topics):  -46457210.907
Per-word Perplexity:  755.178877447
Perplexity (40 topics):  -47294658.5467
Per-word Perplexity:  851.001209258

我已经想到的可能的问题所在:
1.模型运行得不够长,无法正常收敛吗?我将chunksize设置为1000,因此应该有40-50个passes,而在最后一个块中,我看到980个+/1000个文档在50次迭代中收敛。
2.我不理解LDAlda.bound函数的估计值吗?
3.我需要更多地修剪(trim)字典吗?我已经删除了中值TF-IDF分数以下的所有tokens,所以我把原来的字典切成了两半。
我的问题是我用R来构建字典和语料库吗?在文本编辑器中,我比较了从R生成的字典和MM语料库文件到用gensim构建的更小的测试字典/语料库,而在信息如何编码时,我看不到任何差异。我想使用R来构建语料库,所以我确保我使用的是完全相同的语料库,作为online LDA,我将在R中使用最后的模型,而我不知道如何将gensim语料库转换成R文档术语矩阵对象。
我使用的脚本是:
import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

import numpy
import scipy
import gensim

import random
random.seed(11091987)           #set random seed


# load id->word mapping (the dictionary)
id2word =  gensim.corpora.Dictionary.load_from_text('../dict.dict')

# load corpus
## add top line to MM file since R does not automatically add this
## and save new version
with open('../dtm.mtx') as f:
    dtm = f.read()
    dtm = "%%MatrixMarket matrix coordinate real general\n" + dtm

with open('dtm.mtx', 'w+') as f:
    f.write(dtm)


corpus = gensim.corpora.MmCorpus('dtm.mtx')

print id2word
print corpus

# shuffle corpus洗牌语料库
cp = list(corpus)
random.shuffle(cp)

# split into 80% training and 20% test sets
p = int(len(cp) * .8)
cp_train = cp[0:p]
cp_test = cp[p:]

import time
start_time = time.time()

lda = gensim.models.ldamodel.LdaModel(corpus=cp_train, id2word=id2word, num_topics=25,
                                      update_every=1, chunksize=1000, passes=2)

elapsed = time.time() - start_time
print('Elapsed time: '),
print elapsed


print lda.show_topics(topics=-1, topn=10, formatted=True)

print('Perplexity: '),
perplex = lda.bound(cp_test)
print perplex

print('Per-word Perplexity: '),
print numpy.exp2(-perplex / sum(cnt for document in cp_test for _, cnt in document))

elapsed = time.time() - start_time
print('Elapsed time: '),
print elapsed

猜你喜欢

转载自blog.csdn.net/qq_32482091/article/details/81061983
LDA