优化 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
根据gensim
source code、model.wmdistance
returns如下:
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 计算。
我正在使用 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
根据gensim
source code、model.wmdistance
returns如下:
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)
.
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 计算。