pyLDAvis:尝试可视化主题时的验证错误

时间:2017-12-27 21:10:25

标签: python nlp lda topic-modeling

我尝试使用gensim为300000条记录生成主题。在尝试可视化主题时,我收到验证错误。我可以在模型训练后打印主题,但是使用pyLDAvis

失败了
# Running and Training LDA model on the document term matrix.
ldamodel1 = Lda(doc_term_matrix1, num_topics=10, id2word = dictionary1, passes=50, workers = 4)

(ldamodel1.print_topics(num_topics=10, num_words = 10))
 #pyLDAvis
d = gensim.corpora.Dictionary.load('dictionary1.dict')
c = gensim.corpora.MmCorpus('corpus.mm')
lda = gensim.models.LdaModel.load('topic.model')

#error on executing this line
data = pyLDAvis.gensim.prepare(lda, c, d)

在运行pyLDAvis

之后尝试运行时出现以下错误
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
<ipython-input-53-33fd88b65056> in <module>()
----> 1 data = pyLDAvis.gensim.prepare(lda, c, d)
      2 data

C:\ProgramData\Anaconda3\lib\site-packages\pyLDAvis\gensim.py in prepare(topic_model, corpus, dictionary, doc_topic_dist, **kwargs)
    110     """
    111     opts = fp.merge(_extract_data(topic_model, corpus, dictionary, doc_topic_dist), kwargs)
--> 112     return vis_prepare(**opts)

C:\ProgramData\Anaconda3\lib\site-packages\pyLDAvis\_prepare.py in prepare(topic_term_dists, doc_topic_dists, doc_lengths, vocab, term_frequency, R, lambda_step, mds, n_jobs, plot_opts, sort_topics)
    372    doc_lengths      = _series_with_name(doc_lengths, 'doc_length')
    373    vocab            = _series_with_name(vocab, 'vocab')
--> 374    _input_validate(topic_term_dists, doc_topic_dists, doc_lengths, vocab, term_frequency)
    375    R = min(R, len(vocab))
    376 

C:\ProgramData\Anaconda3\lib\site-packages\pyLDAvis\_prepare.py in _input_validate(*args)
     63    res = _input_check(*args)
     64    if res:
---> 65       raise ValidationError('\n' + '\n'.join([' * ' + s for s in res]))
     66 
     67 

ValidationError: 
 * Not all rows (distributions) in topic_term_dists sum to 1.

4 个答案:

答案 0 :(得分:0)

之所以会这样,是因为pyLDAvis程序希望模型中的所有文档主题至少在语料库中显示一次。在创建语料库/文本之后以及在创建模型之前进行一些预处理时,会发生这种情况。

您提供的字典中未使用的模型内部字典中的单词将导致此操作失败,因为现在的概率略小于一个。

您可以通过以下方法解决此问题:将缺少的单词添加到语料库词典中(或将单词添加到语料库并由此创建词典),也可以将此行添加到site-packages \ pyLDAvis \ gensim.py代码中在“断言topic_term_dists.shape [0] == doc_topic_dists.shape [1]”之前(应为〜67行)

topic_term_dists = topic_term_dists / topic_term_dists.sum(axis=1)[:, None]

假设您的代码一直运行到那时,这将使主题分布重新正常化而不会缺少dict项目。但是请注意,将所有术语包括在语料库中会更好。

答案 1 :(得分:0)

这是在我过滤字典后在HDPModel中发生的-我留下了很多零长度的文档,这产生了此错误。在通过corpora.MmCorpus.serialize(args.save_folder + '/gensim.mm', (x for x in corpus if len(x) > 0))将MmCorpus保存到磁盘之前,我消除了它们,这解决了以后运行HDP时的问题。 corpus是我的文本文档的生成器。

答案 2 :(得分:0)

我遇到了相同的验证错误。

我的问题是,即使 let iFileLength = this.files.length; for (let i = 0; i < this.files.length; i++) { /* Update this line */ oHome.aFiles.push(this.files, i); } /* Update method signature */ function readAndPreview(files, index) { const file = files[index]; if (!/\.(jpeg|png|gif|jpg)$/i.test(file.name)) { return alert(file.name + " is not an image"); } var reader = new FileReader(); reader.addEventListener("load", function() { let image = new Image(); image.classList.add('mr-2', 'mt-2', 'w-100', 'h-100'); image.title = file.name; image.src = this.result; let oDiv = document.createElement("div"); oDiv.classList.add('col-md-3', 'mt-2'); oDiv.appendChild(oButton); oDiv.appendChild(image); let oButton = document.createElement("button"); oButton.classList.add('close'); oButton.type = "button"; oButton.innerHTML= "x"; /* Add "image remove" logic, run when oButton is clicked */ oButton.addEventListener("click", function(e) { /* Prevent default behavior of button (if any) */ e.preventDefault(); /* Remove the img and x button */ image.remove(); oButton.remove(); /* Remove file at current index from files array */ files.splice(index, 1); }); oHome.oImgPrev.appendChild(oDiv); }); } 经过了标准化步骤(请参阅PyLDAVISsklearn.py)以确保_row_normdoc_topic_dists的概率总和为1,如果文档中的所有单词均未真正出现在文档术语矩阵(例如0s矩阵)中,则此功能不能确保您的概率等于1。您的概率只能等于0!

对文档向量求和。如果确实为0,则可能要删除该行/文档。

topic_term_dists

答案 3 :(得分:0)

我遇到了这个问题,并通过在生成语料库之前从字典中过滤掉频率非常低的单词来解决它。

dictionary.filter_extremes(no_below=2, no_above=1.0)

我怀疑由于浮点逼近,很多极低概率的总和不会等于 1。