优化 Gensim word mover 的速度距离函数 (wmdistance)

Optimizing Gensim word mover's distance function for speed (wmdistance)

我正在使用 gensim wmdistance 来计算参考句子和其他 1000 个句子之间的相似度。

    model = gensim.models.KeyedVectors.load_word2vec_format(
     'GoogleNews-vectors-negative300.bin', binary=True)
    model.init_sims(replace=True)  

    reference_sentence = "it is a reference sentence"
    other_sentences = [1000 sentences]
    index = 0
    for sentence in other_sentences: 
      distance [index] = model.wmdistance(refrence_sentence, other_sentences)
      index = index + 1

根据gensimsource codemodel.wmdistancereturns如下:

emd(d1, d2, distance_matrix)

其中

d1 =  # Compute nBOW representation of reference_setence.
d2 =  # Compute nBOW representation of other_sentence (one by one).
distance_matrix = see the source code as its a bit too much to paste it here.

对于我的用例,此代码在两个方面效率低下。

1)对于参考语句,它在为距离函数emd(d1, d2, distance_matrix).

重复计算d1(1000次)

2) 此距离函数由来自不同点的多个用户调用,这些用户为相同的 other_sentences 重复 model.wmdistance(doc1, doc2) 的整个过程,并且计算量很大。对于这 1000 次比较,大约需要 7-8 秒。

因此,我想隔离这两个任务。最后计算距离:emd(d1, d2, distance_matrix) 并准备这些输入:d1、d2 和距离矩阵。由于距离矩阵取决于两者,因此至少其输入准备应与最终矩阵计算隔离开来。

我最初的计划是创建三个自定义函数:

d1 = prepared1(reference_sentence)
d2 = prepared2(other_sentence)
distance_matrix inputs = prepare inputs 

是否可以使用此 gensim 函数执行此操作,还是我应该使用自己的自定义版本?有什么想法和解决方案可以更好地处理这个问题吗?

您观察到可以重构和优化此代码以避免重复操作,这是正确的,特别是在针对更大的文档集评估一个 reference/query 文档的常见情况下。 (任何此类改进也将是对 gensim 的欢迎贡献。)

在计算之外简单地准备单个文档可能不会节省很多钱;在每种情况下,都必须计算两个文档之间的所有词到词的距离。预先计算一个更大的 distance_matrix(在相关词汇表和系统内存允许的范围内)可能是有意义的,其中包括许多成对 WMD 计算所需的所有单词。

(预先计算所有单词到单词的距离可能很诱人,词汇表有 300 万个单词,如 GoogleNews 向量集,只有 4 字节的浮点距离,存储它们所有这些都至少需要 18TB。因此,在可管理的文档批次上计算相关词的距离可能更有意义。)

一种可能的开始方式是创建 wmdistance() 的变体,它明确适用于一个文档而不是一组文档,因此可以将 histograms/distance-matrixes 的创建结合起来用于多个文档一次比较。

对于不需要 all WMD 值但只需要前 N 个最近结果的常见情况,原始 WMD 论文中描述了一种优化,其中另一种更快的计算(在那里调用 'RWMD') 可用于推断何时文档不可能出现在前 N 个结果中,从而完全跳过这些文档的完整 WMD 计算。