使用Word2vec判断一组词中哪两个词最相似
Use Word2vec to determine which two words in a group of words is most similar
我正在尝试使用 Word2vec 的 python 包装器。我有一个词嵌入或一组词,可以在下面看到,从它们我试图确定哪两个词彼此最相似。
我该怎么做?
['architect', 'nurse', 'surgeon', 'grandmother', 'dad']
鉴于您使用的是 gensim 的 word2vec,根据您的评论:
为您的嵌入加载或训练模型,然后在您的模型上,您可以调用:
min_distance = float('inf')
min_pair = None
word2vec_model_wv = model.wv # Unsure if this can be done in the loop, but just to be safe efficiency-wise
for candidate_word1 in words:
for candidate_word2 in words:
if candidate_word1 == candidate_word2:
continue # ignore when the two words are the same
distance = word2vec_model_wv.distance(candidate_word1, candidate_word2)
if distance < min_distance:
min_pair = (candidate_word1, candidate_word2)
min_distance = distance
也可能是相似的(我不完全确定是否有区别)。 https://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.similarity
如果像我预期的那样,相似度随着更近的单词变得更大,那么您将想要最大化而不是最小化,并且只需将距离函数调用替换为相似度调用。基本上这只是对的简单 min/max 函数。
@rylan-feldspar 的回答通常是正确的方法并且会起作用,但是您可以使用标准 Python libraries/idioms,尤其是 itertools
,一个列表来更紧凑地做到这一点-理解和排序功能。
例如,首先使用 itertools
中的 combinations()
生成所有候选词对:
from itertools import combinations
candidate_words = ['architect', 'nurse', 'surgeon', 'grandmother', 'dad']
all_pairs = combinations(candidate_words, 2)
然后,用它们的成对相似性装饰这些对:
scored_pairs = [(w2v_model.wv.similarity(p[0], p[1]), p)
for p in all_pairs]
最后,将最相似的对放在最前面,然后报告得分和对:
sorted_pairs = sorted(scored_pairs, reverse=True)
print(sorted_pairs[0]) # first item is most-similar pair
如果你想紧凑但可读性差一点,它可以是(长)“1-liner”:
print(sorted([(w2v_model.wv.similarity(p[0], p[1]), p)
for p in combinations(candidate_words, 2)
], reverse=True)[0])
更新:
整合@ryan-feldspar 关于 max()
的建议,并追求最小化,这也应该可以报告最佳配对(但不是它的分数):
print(max(combinations(candidate_words, 2),
key=lambda p:w2v_model.wv.similarity(p[0], p[1])))
我正在尝试使用 Word2vec 的 python 包装器。我有一个词嵌入或一组词,可以在下面看到,从它们我试图确定哪两个词彼此最相似。
我该怎么做?
['architect', 'nurse', 'surgeon', 'grandmother', 'dad']
鉴于您使用的是 gensim 的 word2vec,根据您的评论:
为您的嵌入加载或训练模型,然后在您的模型上,您可以调用:
min_distance = float('inf')
min_pair = None
word2vec_model_wv = model.wv # Unsure if this can be done in the loop, but just to be safe efficiency-wise
for candidate_word1 in words:
for candidate_word2 in words:
if candidate_word1 == candidate_word2:
continue # ignore when the two words are the same
distance = word2vec_model_wv.distance(candidate_word1, candidate_word2)
if distance < min_distance:
min_pair = (candidate_word1, candidate_word2)
min_distance = distance
也可能是相似的(我不完全确定是否有区别)。 https://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.similarity
如果像我预期的那样,相似度随着更近的单词变得更大,那么您将想要最大化而不是最小化,并且只需将距离函数调用替换为相似度调用。基本上这只是对的简单 min/max 函数。
@rylan-feldspar 的回答通常是正确的方法并且会起作用,但是您可以使用标准 Python libraries/idioms,尤其是 itertools
,一个列表来更紧凑地做到这一点-理解和排序功能。
例如,首先使用 itertools
中的 combinations()
生成所有候选词对:
from itertools import combinations
candidate_words = ['architect', 'nurse', 'surgeon', 'grandmother', 'dad']
all_pairs = combinations(candidate_words, 2)
然后,用它们的成对相似性装饰这些对:
scored_pairs = [(w2v_model.wv.similarity(p[0], p[1]), p)
for p in all_pairs]
最后,将最相似的对放在最前面,然后报告得分和对:
sorted_pairs = sorted(scored_pairs, reverse=True)
print(sorted_pairs[0]) # first item is most-similar pair
如果你想紧凑但可读性差一点,它可以是(长)“1-liner”:
print(sorted([(w2v_model.wv.similarity(p[0], p[1]), p)
for p in combinations(candidate_words, 2)
], reverse=True)[0])
更新:
整合@ryan-feldspar 关于 max()
的建议,并追求最小化,这也应该可以报告最佳配对(但不是它的分数):
print(max(combinations(candidate_words, 2),
key=lambda p:w2v_model.wv.similarity(p[0], p[1])))