Python:如何更快地计算Jaccard相似度

时间:2018-06-09 04:14:28

标签: python-3.x machine-learning nlp

lst_train中约有98,000个句子(长度为5-100个单词),lst_test中有大约1000个句子(长度为5-100个单词)。对于lst_test中的每个句子,我想查找它是否被lst_train中的句子抄袭。如果句子是剽窃的,我应该在lst_train中返回id,否则返回null。

现在我想计算lst_test中每个句子相对于lst_train中每个句子的jaccard相似度。这是我的代码,b.JaccardSim计算两个句子'jaccard相似度:

lst_all_p = []
for i in range(len(lst_test)):
    print('i:', i)
    lst_p = []
    for j in range(len(lst_train)):
        b = textSimilarity.TextSimilarity(lst_test[i], lst_train[j])
        lst_p.append(b.JaccardSim(b.str_a,b.str_b))
    lst_all_p.append(lst_p)

但是我发现每次用lst_train中的每个句子计算一个句子都超过1分钟。由于大约有1000个句子,完成它可能需要大约1000分钟。太长了。

你们知道如何让计算速度更快或者更好的方法来解决检测句子的问题是从lst_train的句子中抄袭的吗?

2 个答案:

答案 0 :(得分:1)

改变你的方法可能会更好。 Jaccard相似性不是超级计算上的积极性,但是如果你必须对数据集中的每个元素都这样做,那么任何非平凡的相似性计算都会很慢。

如果您想查找剽窃,您应该查看近似重复检测位置敏感哈希MinHashSimHash是很好的起点,datasketch库也可能会有所帮助。

请注意,对于许多应用程序来说,矢量化句子并在向量空间中搜索近似句子是有效的。然而,这是有效的,因为它能够理解同义词 - 因为你正在寻找抄袭,你正在寻找精确的副本,所以基于单词矢量的方法最终可能会违背你的目标。

答案 1 :(得分:0)

如polm23所建议,datasektch库非常适合您的任务。

GitHub repo显示了一个示例,其中datasketch提供的LSH实现用于计算文本文档之间的Jaccard相似度。