用word2vec通过相似度替换随机词

Replace random word by similarity with word2vec

我想用 word2vec 中最相似的词替换句子中的随机词,例如句子 question = 'Can I specify which GPU to use?' 中的词。

我使用这种递归方法是因为使用 split 函数,一些单词(如 to)不在 word2vecmodel 中:

import gensim.models.keyedvectors as word2vec
import random as rd

model = word2vec.KeyedVectors.load_word2vec_format('/Users/nbeau/Desktop/Word2vec/model/GoogleNews-vectors-negative300.bin', binary=True)

def similar_word(sentence, size):
    pos_to_replace = rd.randint(0, size-1)
    try:
        similarity = model.most_similar(positive = [sentence[pos_to_replace]])
        similarity = similarity[0][0]
    except KeyError:
        similarity, pos_to_replace = test(sentence, size)
        return similarity, pos_to_replace
    return similarity, pos_to_replace

question = question.split()
size = len(question)
similarity, pos_to_replace = similar_word(question, size)
sentence[pos_to_replace] = similarity

我想知道是否有更好的方法来避免word2vec模型中没有的词。

一些想法:

  • 如果 kv_model 是你的 KeyedVectors 模型,你可以做 'to' in kv_model 来测试一个词是否存在,而不是尝试然后抓住 KeyError。但乐观和发现错误也是一个常见的习惯用法!

  • 您的递归不一定会退出:如果提供的文本不包含已知词,它会不断地递归尝试(或者可能在达到某个调用深度实现限制时)。此外,它可能会多次尝试同一个词。

我建议使用循环而不是递归,并使用 Python 的 random.shuffle() 方法来创建所有潜在索引的单个随机排列。然后,依次尝试每个,return一旦可以替换就立即尝试,或者如果无法替换则指示失败。

保持相同的方法return-签名:

def similar_word(sentence):
    indexes = range(len(sentence))
    random.shuffle(indexes)
    for i in indexes:
        if sentence[i] in kv_model:
            return model.most_similar(sentence[i], topn=1)[0][0], i
    return None, -1  # no replacement was possible

(但与你的问题分开:如果 100% 的时间,函数的结果用于执行替换,我只是将替换移动到函数内部,改变传入的 sentence。并且该函数可以报告它进行了多少次替换:0 表示失败,1 表示通常情况——也许将来可以接受一个参数来请求超过 1 次替换。)