Eri*_*oda 6 nlp word2vec spacy word-embedding
我正在使用 spaCy 作为主题建模解决方案的一部分,并且我需要将派生词向量映射到词向量词汇表中的“最接近”或“最相似”词。
我看到 gensim 有一个函数 (WordEmbeddingsKeyedVectors.similar_by_vector) 来计算这个,但我想知道 spaCy 是否有这样的东西来将向量映射到其词汇表 (nlp.vocab) 中的单词?
经过一些实验,我找到了一个 scikit 函数(scikit.spatial.distance 中的 cdist),它在输入向量的向量空间中找到一个“接近”向量。
# Imports
from scipy.spatial import distance
import spaCy
# Load the spacy vocabulary
nlp = spacy.load("en_core_web_lg")
# Format the input vector for use in the distance function
# In this case we will artificially create a word vector from a real word ("frog")
# but any derived word vector could be used
input_word = "frog"
p = np.array([nlp.vocab[input_word].vector])
# Format the vocabulary for use in the distance function
ids = [x for x in nlp.vocab.vectors.keys()]
vectors = [nlp.vocab.vectors[x] for x in ids]
vectors = np.array(vectors)
# *** Find the closest word below ***
closest_index = distance.cdist(p, vectors).argmin()
word_id = ids[closest_index]
output_word = nlp.vocab[word_id].text
# output_word is identical, or very close, to the input word
Run Code Online (Sandbox Code Playgroud)
关于这个答案的警告。传统上,单词相似度(在 gensim、spacy 和 nltk 中)使用余弦相似度,而默认情况下,scipy 的 cdist 使用欧几里得距离。您可以获得与相似度不同的余弦距离,但它们是相关的。要复制 gensim 的计算,请将您的 cdist 调用更改为以下内容:
distance.cdist(p, vectors, metric='cosine').argmin()
Run Code Online (Sandbox Code Playgroud)
但是,您还应该注意,scipy 测量的余弦距离是从余弦相似度“向后”的,其中“cosine dist”= 1 - cos x(x 是向量之间的角度),因此要匹配/复制 gensim 数,您必须减去你的答案之一(当然,采用 MAX 参数——类似的向量更接近于 1)。这是一个非常微妙的差异,但可能会引起很大的混乱。
相似的向量应该有很大的(接近 1)相似度,而距离很小(接近于 0)。
余弦相似度可以为负(意味着向量具有相反的方向),但它们的 DISTANCE 将为正(距离应该是)。
来源:https : //docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.cdist.html
在 spacy 中做相似性的还有以下几点:
import spacy
nlp = spacy.load("en_core_web_md")
x = nlp("man")
y = nlp("king")
print(x.similarity(y))
print(x.similarity(x))
Run Code Online (Sandbox Code Playgroud)
是的,spacy 有一个 API 方法可以做到这一点,就像 KeyedVectors.similar_by_vector 一样:
import numpy as np
import spacy
nlp = spacy.load("en_core_web_lg")
your_word = "king"
ms = nlp.vocab.vectors.most_similar(
np.asarray([nlp.vocab.vectors[nlp.vocab.strings[your_word]]]), n=10)
words = [nlp.vocab.strings[w] for w in ms[0][0]]
distances = ms[2]
print(words)
['King', 'KIng', 'king', 'KING', 'kings', 'KINGS', 'Kings', 'PRINCE', 'Prince', 'prince']
Run Code Online (Sandbox Code Playgroud)
(单词在 中没有正确归一化sm_core_web_lg,但您可以使用其他模型并观察更具代表性的输出)。
| 归档时间: |
|
| 查看次数: |
3456 次 |
| 最近记录: |