使用 Gensim,在我训练自己的模型后,我可以使用model.wv.most_similar('cat', topn=5)并获取cat向量空间中最接近的 5 个单词的列表。例如:
from gensim.models import Word2Vec
model = Word2Vec.load('mymodel.model')
In: model.wv.most_similar('cat', topn=5)
Out: ('kitten', .99)
('dog', .98)
...
Run Code Online (Sandbox Code Playgroud)
使用 spaCy,根据文档,我可以执行以下操作:
import spacy
nlp = spacy.load('en_core_web_md')
tokens = nlp(u'dog cat banana')
for token1 in tokens:
for token2 in tokens:
print(token1.text, token2.text, token1.similarity(token2))
Run Code Online (Sandbox Code Playgroud)
它给出了指定字符串中标记的相似性。但是通过文档和搜索,我无法弄清楚是否有一种 gensim 类型的方式来列出带有nlp = spacy.load('en_core_web_lg')或的预加载模型的所有相似词nlp = spacy.load('en_vectors_web_lg')。有没有办法做到这一点?
小智 6
我使用了安迪的回应,它工作正常但速度很慢。为了解决这个问题,我采用了下面的方法。
SpaCy 在后端使用余弦相似度来计算.similarity。因此,我决定word.similarity(w)用其优化的对应物替换。我使用的优化方法是cosine_similarity_numba(w.vector, word.vector),如下所示,它使用 Numba 库来加速计算。您应该用下面的行替换 most_similar 方法中的第 12 行。
by_similarity = sorted(queries, key=lambda w: cosine_similarity_numba(w.vector, word.vector), reverse=True)
Run Code Online (Sandbox Code Playgroud)
该方法的速度提高了 2-3 倍,这对我来说至关重要。
from numba import jit
@jit(nopython=True)
def cosine_similarity_numba(u:np.ndarray, v:np.ndarray):
assert(u.shape[0] == v.shape[0])
uv = 0
uu = 0
vv = 0
for i in range(u.shape[0]):
uv += u[i]*v[i]
uu += u[i]*u[i]
vv += v[i]*v[i]
cos_theta = 1
if uu != 0 and vv != 0:
cos_theta = uv/np.sqrt(uu*vv)
return cos_theta
Run Code Online (Sandbox Code Playgroud)
我在这篇文章中更详细地解释了它:如何在 SpaCy 中构建快速的“最相似词”方法
小智 5
它不是开箱即用的。但是,基于这个问题(https://github.com/explosion/spaCy/issues/276)这里有一个代码可以让它按你的意愿工作。
import spacy
import numpy as np
nlp = spacy.load('en_core_web_lg')
def most_similar(word, topn=5):
word = nlp.vocab[str(word)]
queries = [
w for w in word.vocab
if w.is_lower == word.is_lower and w.prob >= -15 and np.count_nonzero(w.vector)
]
by_similarity = sorted(queries, key=lambda w: word.similarity(w), reverse=True)
return [(w.lower_,w.similarity(word)) for w in by_similarity[:topn+1] if w.lower_ != word.lower_]
most_similar("dog", topn=3)
Run Code Online (Sandbox Code Playgroud)