在gensim Word2Vec模型中匹配单词和向量
Matching words and vectors in gensim Word2Vec model
我已经让 gensim Word2Vec 实现为我计算了一些词嵌入。据我所知,一切都非常顺利;现在我正在对创建的词向量进行聚类,希望得到一些语义分组。
下一步,我想查看每个集群中包含的单词(而不是向量)。 IE。如果我有嵌入向量 [x, y, z]
,我想找出这个向量代表的实际单词。我可以通过调用 model.vocab
获得 words/Vocab 项,通过 model.syn0
获得词向量。但是我找不到明确匹配这些的位置。
这比我预期的要复杂,我觉得我可能错过了这样做的明显方法。感谢您的帮助!
问题:
将单词与 Word2Vec ()
创建的嵌入向量匹配——我该怎么做?
我的做法:
创建模型(下面的代码*)后,我现在想将分配给每个单词的索引(在 build_vocab()
阶段)与输出为 model.syn0
的向量矩阵相匹配。
于是
for i in range (0, newmod.syn0.shape[0]): #iterate over all words in model
print i
word= [k for k in newmod.vocab if newmod.vocab[k].__dict__['index']==i] #get the word out of the internal dicationary by its index
wordvector= newmod.syn0[i] #get the vector with the corresponding index
print wordvector == newmod[word] #testing: compare result of looking up the word in the model -- this prints True
有没有更好的方法,例如通过将向量输入模型来匹配单词?
这甚至能让我得到正确的结果吗?
*我创建词向量的代码:
model = Word2Vec(size=1000, min_count=5, workers=4, sg=1)
model.build_vocab(sentencefeeder(folderlist)) #sentencefeeder puts out sentences as lists of strings
model.save("newmodel")
我找到了 类似但还没有真正回答。
如果您只想将 word 映射到 vector,您可以简单地使用 []
运算符,例如model["hello"]
会给你hello对应的向量
如果您需要从向量中恢复单词,您可以按照您的建议遍历向量列表并检查匹配项。然而,这是低效的并且不是 pythonic 的。一个方便的解决方案是使用word2vec模型的similar_by_vector
方法,像这样:
import gensim
documents = [['human', 'interface', 'computer'],
['survey', 'user', 'computer', 'system', 'response', 'time'],
['eps', 'user', 'interface', 'system'],
['system', 'human', 'system', 'eps'],
['user', 'response', 'time'],
['trees'],
['graph', 'trees'],
['graph', 'minors', 'trees'],
['graph', 'minors', 'survey']]
model = gensim.models.Word2Vec(documents, min_count=1)
print model.similar_by_vector(model["survey"], topn=1)
输出:
[('survey', 1.0000001192092896)]
其中数字代表相似度。
然而,这种方法仍然效率低下,因为它仍然需要扫描所有的词向量来搜索最相似的词向量。解决您的问题的最佳方法是 找到一种在聚类过程中跟踪向量的方法,这样您就不必依赖昂贵的反向映射。
正如@bpachev 提到的,gensim 确实有一个按向量搜索的选项,即 similar_by_vector
。
然而,它实现了一种强力线性搜索,即计算给定向量与词汇表中所有单词的向量之间的余弦相似度,并给出顶部邻居。如另一个 中所述,另一种选择是使用 FLANN 等近似最近邻搜索算法。
分享一个展示相同内容的要点:
https://gist.github.com/kampta/139f710ca91ed5fabaf9e6616d2c762b
我已经搜索了很长时间以找到 syn0 矩阵和词汇表之间的映射...这里是答案:使用 model.index2word
这只是按正确顺序排列的单词列表!
这不在官方文档中(为什么?)但可以直接在源代码中找到:https://github.com/RaRe-Technologies/gensim/blob/3b9bb59dac0d55a1cd6ca8f984cead38b9cb0860/gensim/models/word2vec.py#L441
所以我找到了一个简单的方法来做到这一点,其中 nmodel
是您的模型的名称。
#zip the two lists containing vectors and words
zipped = zip(nmodel.wv.index2word, nmodel.wv.syn0)
#the resulting list contains `(word, wordvector)` tuples. We can extract the entry for any `word` or `vector` (replace with the word/vector you're looking for) using a list comprehension:
wordresult = [i for i in zipped if i[0] == word]
vecresult = [i for i in zipped if i[1] == vector]
这是基于gensim code。对于旧版本的 gensim,您可能需要在模型后删除 wv
。
我已经让 gensim Word2Vec 实现为我计算了一些词嵌入。据我所知,一切都非常顺利;现在我正在对创建的词向量进行聚类,希望得到一些语义分组。
下一步,我想查看每个集群中包含的单词(而不是向量)。 IE。如果我有嵌入向量 [x, y, z]
,我想找出这个向量代表的实际单词。我可以通过调用 model.vocab
获得 words/Vocab 项,通过 model.syn0
获得词向量。但是我找不到明确匹配这些的位置。
这比我预期的要复杂,我觉得我可能错过了这样做的明显方法。感谢您的帮助!
问题:
将单词与 Word2Vec ()
创建的嵌入向量匹配——我该怎么做?
我的做法:
创建模型(下面的代码*)后,我现在想将分配给每个单词的索引(在 build_vocab()
阶段)与输出为 model.syn0
的向量矩阵相匹配。
于是
for i in range (0, newmod.syn0.shape[0]): #iterate over all words in model
print i
word= [k for k in newmod.vocab if newmod.vocab[k].__dict__['index']==i] #get the word out of the internal dicationary by its index
wordvector= newmod.syn0[i] #get the vector with the corresponding index
print wordvector == newmod[word] #testing: compare result of looking up the word in the model -- this prints True
有没有更好的方法,例如通过将向量输入模型来匹配单词?
这甚至能让我得到正确的结果吗?
*我创建词向量的代码:
model = Word2Vec(size=1000, min_count=5, workers=4, sg=1)
model.build_vocab(sentencefeeder(folderlist)) #sentencefeeder puts out sentences as lists of strings
model.save("newmodel")
我找到了
如果您只想将 word 映射到 vector,您可以简单地使用 []
运算符,例如model["hello"]
会给你hello对应的向量
如果您需要从向量中恢复单词,您可以按照您的建议遍历向量列表并检查匹配项。然而,这是低效的并且不是 pythonic 的。一个方便的解决方案是使用word2vec模型的similar_by_vector
方法,像这样:
import gensim
documents = [['human', 'interface', 'computer'],
['survey', 'user', 'computer', 'system', 'response', 'time'],
['eps', 'user', 'interface', 'system'],
['system', 'human', 'system', 'eps'],
['user', 'response', 'time'],
['trees'],
['graph', 'trees'],
['graph', 'minors', 'trees'],
['graph', 'minors', 'survey']]
model = gensim.models.Word2Vec(documents, min_count=1)
print model.similar_by_vector(model["survey"], topn=1)
输出:
[('survey', 1.0000001192092896)]
其中数字代表相似度。
然而,这种方法仍然效率低下,因为它仍然需要扫描所有的词向量来搜索最相似的词向量。解决您的问题的最佳方法是 找到一种在聚类过程中跟踪向量的方法,这样您就不必依赖昂贵的反向映射。
正如@bpachev 提到的,gensim 确实有一个按向量搜索的选项,即 similar_by_vector
。
然而,它实现了一种强力线性搜索,即计算给定向量与词汇表中所有单词的向量之间的余弦相似度,并给出顶部邻居。如另一个
分享一个展示相同内容的要点: https://gist.github.com/kampta/139f710ca91ed5fabaf9e6616d2c762b
我已经搜索了很长时间以找到 syn0 矩阵和词汇表之间的映射...这里是答案:使用 model.index2word
这只是按正确顺序排列的单词列表!
这不在官方文档中(为什么?)但可以直接在源代码中找到:https://github.com/RaRe-Technologies/gensim/blob/3b9bb59dac0d55a1cd6ca8f984cead38b9cb0860/gensim/models/word2vec.py#L441
所以我找到了一个简单的方法来做到这一点,其中 nmodel
是您的模型的名称。
#zip the two lists containing vectors and words
zipped = zip(nmodel.wv.index2word, nmodel.wv.syn0)
#the resulting list contains `(word, wordvector)` tuples. We can extract the entry for any `word` or `vector` (replace with the word/vector you're looking for) using a list comprehension:
wordresult = [i for i in zipped if i[0] == word]
vecresult = [i for i in zipped if i[1] == vector]
这是基于gensim code。对于旧版本的 gensim,您可能需要在模型后删除 wv
。