首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在python中使用gensim的LSI

在python中使用gensim的LSI
EN

Stack Overflow用户
提问于 2011-06-09 10:20:59
回答 3查看 7.3K关注 0票数 4

我正在使用Python的gensim库进行潜在语义索引。我遵循了网站上的教程,它工作得很好。现在,我正在尝试对其进行一些修改;我希望在每次添加文档时都运行lsi模型。

下面是我的代码:

代码语言:javascript
复制
stoplist = set('for a of the and to in'.split())
num_factors=3
corpus = []

for i in range(len(urls)):
 print "Importing", urls[i]
 doc = getwords(urls[i])
 cleandoc = [word for word in doc.lower().split() if word not in stoplist]
 if i == 0:
  dictionary = corpora.Dictionary([cleandoc])
 else:
  dictionary.addDocuments([cleandoc])
 newVec = dictionary.doc2bow(cleandoc)
 corpus.append(newVec)
 tfidf = models.TfidfModel(corpus)
 corpus_tfidf = tfidf[corpus]
 lsi = models.LsiModel(corpus_tfidf, numTopics=num_factors, id2word=dictionary)
 corpus_lsi = lsi[corpus_tfidf]

geturls是我编写的函数,它以字符串的形式返回网站的内容。同样,如果我等到处理完所有文档后再执行tfidf和lsi,它也是有效的,但这不是我想要的。我想在每次迭代中都这样做。不幸的是,我得到了这个错误:

代码语言:javascript
复制
    Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "streamlsa.py", line 51, in <module>
    lsi = models.LsiModel(corpus_tfidf, numTopics=num_factors, id2word=dictionary)
  File "/Library/Python/2.6/site-packages/gensim-0.7.8-py2.6.egg/gensim/models/lsimodel.py", line 303, in __init__
    self.addDocuments(corpus)
  File "/Library/Python/2.6/site-packages/gensim-0.7.8-py2.6.egg/gensim/models/lsimodel.py", line 365, in addDocuments
    self.printTopics(5) # TODO see if printDebug works and remove one of these..
  File "/Library/Python/2.6/site-packages/gensim-0.7.8-py2.6.egg/gensim/models/lsimodel.py", line 441, in printTopics
    self.printTopic(i, topN = numWords)))
  File "/Library/Python/2.6/site-packages/gensim-0.7.8-py2.6.egg/gensim/models/lsimodel.py", line 433, in printTopic
    return ' + '.join(['%.3f*"%s"' % (1.0 * c[val] / norm, self.id2word[val]) for val in most])
  File "/Library/Python/2.6/site-packages/gensim-0.7.8-py2.6.egg/gensim/corpora/dictionary.py", line 52, in __getitem__
    return self.id2token[tokenid] # will throw for non-existent ids
KeyError: 1248

通常错误会在第二个文档中弹出。我想我明白它在告诉我什么(字典索引很糟糕),我就是不明白为什么。我尝试了很多不同的方法,但似乎都不起作用。有人知道这是怎么回事吗?

谢谢!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-14 20:04:42

这是gensim中的一个bug,在gensim中,反向id->word映射被缓存,但是缓存在addDocuments()之后没有更新。

它在2011年的提交中得到了修复:https://github.com/piskvorky/gensim/commit/b88225cfda8570557d3c72b0820fefb48064a049

票数 4
EN

Stack Overflow用户

发布于 2011-06-09 14:17:45

好吧,所以我找到了一个解决方案,尽管不是最优的。

如果您使用corpora.Dictionary创建字典,然后使用dictionary.addDocuments立即添加文档,那么一切都会正常工作。

但是,如果您在这两个调用之间使用字典(通过调用dictionary.doc2bow或使用id2word将字典附加到大规模集成电路模型),那么您的字典将被“冻结”并且无法更新。你可以调用dictionary.addDocuments,它会告诉你它已经更新了,甚至还会告诉你新字典有多大,例如:

代码语言:javascript
复制
INFO:dictionary:built Dictionary(6627 unique tokens) from 8 documents (total 24054 corpus positions)

但是当你引用任何一个新的索引时,你会得到一个错误。我不确定这是一个bug,还是故意的(无论出于什么原因),但至少gensim报告成功地将文档添加到字典的事实肯定是一个bug。

首先,我尝试将所有字典调用放在单独的函数中,其中只应修改字典的本地副本。好吧,它还是会坏的。这对我来说很奇怪,我也不知道为什么。

我的下一步是尝试使用copy.copy传递一个字典副本。这是可行的,但显然会使用更多的开销。但是,它将允许您维护语料库和字典的工作副本。然而,对我来说,这里最大的缺点是,这个解决方案不允许我使用filterTokens删除在语料库中只出现一次的单词,因为这需要修改字典。

我的另一个解决方案是在每次迭代中简单地重建所有内容(语料库、字典、lsi和tfidf模型)。对于我的小样本数据集,这会给我带来稍微好一点的结果,但不能扩展到非常大的数据集,而不会引起内存问题。不过,就目前而言,这是我正在做的事情。

如果任何有经验的gensim用户有更好的(和更好的内存友好)解决方案,这样我就不会遇到更大的数据集的问题,请让我知道!

票数 1
EN

Stack Overflow用户

发布于 2013-08-13 02:42:27

在doc2bow中,您可以设置allow_update = True,它会在每次doc2bow迭代时自动更新您的字典

http://radimrehurek.com/gensim/corpora/dictionary.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6287411

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档