4

Python の gensim ライブラリを使用して、潜在的なセマンティック インデックス作成を行っています。ウェブサイトのチュートリアルに従ったところ、かなりうまく機能しました。今、私はそれを少し修正しようとしています。ドキュメントが追加されるたびに lsi モデルを実行したい。

これが私のコードです:

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 は、Web サイトのコンテンツを文字列として返す関数です。繰り返しますが、tfidf と lsi を実行する前にすべてのドキュメントを処理するまで待っていれば機能しますが、それは私が望んでいることではありません。私は各反復でそれをやりたいです。残念ながら、次のエラーが表示されます。

    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

通常、エラーは 2 番目のドキュメントで表示されます。私はそれが私に言っていることを理解していると思います(辞書のインデックスは悪いです)が、なぜなのかわかりません。私はさまざまなことを試しましたが、何もうまくいかないようです。誰が何が起こっているのか知っていますか?

ありがとう!

4

3 に答える 3

4

これは gensim のバグで、逆の id->word マッピングがキャッシュされますが、キャッシュは後で更新されませんでしたaddDocuments()

2011 年のこのコミットで修正されました: https://github.com/piskvorky/gensim/commit/b88225cfda8570557d3c72b0820fefb48064a049

于 2011-06-14T12:04:42.087 に答える
1

わかりましたので、最適な解決策ではありませんが、解決策を見つけました。

で辞書を作成corpora.Dictionaryし、すぐに でドキュメントを追加するとdictionary.addDocuments、すべて正常に機能します。

ただし、これら 2 つの呼び出しの間に辞書を使用する場合(辞書を呼び出すdictionary.doc2bowか、または を使用して辞書を lsi モデルにアタッチすることによりid2word)、辞書は「凍結」され、更新できません。を呼び出すdictionary.addDocumentsと、更新されたことがわかります。また、新しい辞書の大きさもわかります。たとえば、次のようになります。

INFO:dictionary:built Dictionary(6627 unique tokens) from 8 documents (total 24054 corpus positions)

ただし、新しいインデックスのいずれかを参照すると、エラーが発生します。これがバグなのか、(何らかの理由で) 意図されたものなのかはわかりませんが、少なくとも gensimが文書を辞書に正常に追加したと報告するという事実は確かにバグです。

最初に、ディクショナリのローカル コピーのみを変更する必要がある別の関数にディクショナリ呼び出しを入れてみました。まあ、それでも壊れます。これは私にとって奇妙で、その理由がわかりません。

私の次のステップは、 を使用して辞書のコピーを渡すことでしたcopy.copy。これは機能しますが、明らかにオーバーヘッドが少し増えます。ただし、コーパスと辞書の作業コピーを維持することはできます。ただし、ここでの最大の欠点は、このソリューションでは、 を使用してコーパスに一度だけ出現した単語を削除できないことですfilterTokens。これには、辞書の変更が必要になるためです。

私のもう 1 つの解決策は、反復ごとにすべて (コーパス、辞書、lsi および tfidf モデル) を単純に再構築することです。私の小さなサンプル データセットでは、これにより若干良い結果が得られますが、メモリの問題を発生させずに非常に大きなデータセットに拡張することはできません。それでも、今のところこれは私がしていることです。

経験豊富な gensim ユーザーが、より大きなデータセットで問題に遭遇しないように、より優れた (そしてよりメモリに優しい) ソリューションを持っている場合は、お知らせください!

于 2011-06-09T06:17:45.147 に答える