我使用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
会返回以下内容:
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_sentence重复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
功能执行此操作,还是应该使用自己的自定义版本?有什么想法和解决方案可以更好地解决这个问题吗?
答案 0 :(得分:2)
你是正确的观察到这个代码可以重构&优化以避免重复操作,尤其是在针对更大的文档集评估一个引用/查询doc的常见情况下。 (任何此类改进也将是对gensim的一个受欢迎的贡献。)
简单地在计算之外准备单个文档可能不会带来很大的节省;在每种情况下,必须计算两个文档之间的所有单词到单词的距离。预先计算更大的distance_matrix
(在相关词汇和系统内存允许的范围内)可能是有意义的,其中包括许多成对WMD计算所需的所有单词。
(尽管可能会预测所有的单词到单词的距离,使用像GoogleNews
向量集这样的300万字的词汇,而仅仅是4字节的浮点距离,将它们全部存储起来很诱人至少需要18TB。因此,在可管理的批次文件上计算相关单词的距离可能更有意义。)
一种可能的启动方式是创建一个wmdistance()
的变体,它明确地对一个文档而不是一组文档起作用,因此可以组合直方图/距离矩阵的创建,用于许多比较。一旦。
对于不需要所有 WMD值但只想要前N个最近结果的常见情况,在原始WMD文件中描述了一个优化,其中另一个更快的计算(称为'RWMD') )当文件不可能出现在前N个结果中时,可以用来推断,因此完全跳过那些文档的完整WMD计算。