首页 > 解决方案 > IndexError:索引超出范围 - word2vec

问题描述

我已经word_vectors使用大小 = 512 的 Gensim 包训练了一个名为 的 word2vec 模型。

fname = get_tmpfile('word2vec.model')
word_vectors = KeyedVectors.load(fname, mmap='r')

现在,我创建了一个新的 Numpy 数组(大小也为 512),并将其添加到 word2vec 中,如下所示:

vector = (rand(512)-0.5) *20
word_vectors.add('koffie', vector)

这样做似乎很好,即使我打电话

word_vectors['koffie']

正如预期的那样,我将数组作为输出。

但是,当我想在模型中查找最相似的单词并运行以下代码时:

word_vectors.most_similar('koffie')

我收到以下错误:

Traceback (most recent call last):

  File "<ipython-input-283-ce992786ce89>", line 1, in <module>
    word_vectors.most_similar('koffie')

  File "C:\Users\20200016\AppData\Local\Continuum\anaconda3\envs\ldaword2vec\lib\site-packages\gensim\models\keyedvectors.py", line 553, in most_similar
    mean.append(weight * self.word_vec(word, use_norm=True))

  File "C:\Users\20200016\AppData\Local\Continuum\anaconda3\envs\ldaword2vec\lib\site-packages\gensim\models\keyedvectors.py", line 461, in word_vec
    result = self.vectors_norm[self.vocab[word].index]

IndexError: index 146139 is out of bounds for axis 0 with size 146138


word_vector.size()
Traceback (most recent call last):

  File "<ipython-input-284-2606aca38446>", line 1, in <module>
    word_vector.size()

NameError: name 'word_vector' is not defined

该错误似乎表明我的索引在这里不正确。但是由于我只是间接索引(使用键而不是实际的数字索引),我看不到我需要在这里更改什么。

谁知道这里出了什么问题?我能做些什么来克服这个错误?

标签: python-3.xnumpygensimword2vecindex-error

解决方案


第一次执行 a.most_similar()时,一个KeyedVectors实例(在 gensim 版本到 3.8.3 中)将创建一个单位归一化向量的缓存,以协助所有后续的批量相似性操作,并将其放置在.vectors_norm.

看起来您添加的新向量没有刷新/重新计算/扩展缓存.vectors_norm- 最初KeyedVectors类和.most_similar()操作的设计不是考虑到不断增长或不断变化的向量集,而是作为一个实用程序训练后,冻结的向量集。

所以这就是你的原因IndexError

您应该能够通过明确清除.vectors_norm任何时候对 进行修改/添加来解决此问题KeyedVectors,例如:

word_vectors.vectors_norm = None

(这在 gensim 的下一个 4.0.0 版本中不应该是必需的,但我会仔细检查那里没有类似的问题。)

分别地:

  • 您的'word_vector' is not defined错误仅仅是因为您似乎已将“s”从您选择的变量名中删除word_vectors

  • 您可能不需要使用 gensim-testing-utility-method get_tmpfile()- 只需使用您自己明确的、有意的文件系统路径来保存和加载

  • 是否适合使用KeyedVectors.load()取决于保存的内容。如果您实际上是在保存一个完整的Word2Vec类实例(不仅仅是向量),那么使用Word2Vec.load()会更合适。


推荐阅读