使用Word2vec确定一组单词中哪两个单词最相似

4

我想使用围绕Word2vec的Python包装器。下面是一个单词嵌入或一组单词,我正在尝试从中确定哪两个单词最相似。

我该怎么做?

['architect', 'nurse', 'surgeon', 'grandmother', 'dad']


你能否发布一下你目前使用Word2Vec Python包的代码?另外,你能具体提供你正在使用的封装器的链接吗?因为有不止一个。 - Will T
如果您正在使用gensim的word2vec,那么https://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.most_similar_to_given可能是您想要的东西。 - Will T
如果你正在使用Danielfrg的Python Google Word2Vec接口,那么这里有一些示例:https://nbviewer.jupyter.org/github/danielfrg/word2vec/blob/master/examples/word2vec.ipynb#Predictions 我强烈建议查看预测部分中的最后一个示例。 - Will T
@RylanFeldspar 我正在使用Gensim。 - Kann
@RylanFeldspar,对于Gensim而言,它并不能做到我所要求的功能。给定 ['architect', 'nurse', 'surgeon', 'grandmother', 'dad'],我希望返回最相似的两个单词,例如 ['nurse', 'surgeon']。 - Kann
2个回答

2

@rylan-feldspar的回答通常是正确的方法,会起作用,但您可以使用标准Python库/惯用语更紧凑地完成此操作,特别是使用itertools、列表推导式和排序函数。

例如,首先使用itertools中的combinations()生成所有候选单词对:

Original Answer翻译成"最初的回答"

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

如果您想要更加紧凑但可读性稍差的话,可以使用(较长的)“一行代码”:最初的回答。
print(sorted([(w2v_model.wv.similarity(p[0], p[1]), p) 
              for p in combinations(candidate_words, 2)
             ], reverse=True)[0])

更新:

结合 @ryan-feldspar 的建议,采用最小化的方式,以下代码也可以报告最佳匹配对(但不包括其得分):

print(max(combinations(candidate_words, 2),
          key=lambda p:w2v_model.wv.similarity(p[0], p[1])))

1
我必须承认,我从未听说过“combinations”!每天都有新的学习!如果我们只是寻找最小值,正如问题提出者建议的那样,对于长列表的得分对来说,使用相似性的max(scored_pairs, key=lambda p: p[1])或差异的min可能更有效。 - Will T
通常人们想要前几个,所以我的习惯是排序,但你说得对——max()比完整排序略微更有效率,可以在单次遍历中抓取最佳项。由于元组中分数在第一个([0])索引中,我认为您不需要指定一个key:逐个元素进行比较,从p[0]开始,只有在早期元素中存在平局时才会继续比较p[1](等等)。 (但您也可以完全跳过推导/排序,并使用计算对的相似性的max()key函数!) - gojomo

2

如果你正在使用gensim的word2vec,根据你的评论:

加载或训练嵌入模型,然后在你的模型上调用:

most_similar()

以获取与给定单词最相似的单词列表。

原始回答:Original Answer

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.distancehttps://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.similarity

您还可以使用 https://radimrehurek.com/gensim/models/keyedvectors.html#gensim.models.keyedvectors.WordEmbeddingsKeyedVectors.distances 来减少对模型的调用,但我将把这个练习留给读者去尝试。 - Will T

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接