3

我目前正在创建一个程序,可以在文本文档(+5000 文档)的语料库中计算接近重复的分数。我正在使用 Simhash 生成文档的 uniq 足迹(感谢这个github repo

我的数据是:

data = {
    1: u'Im testing simhash algorithm.',
    2: u'test of simhash algorithm',
    3: u'This is simhash test.',
}

这给了我3个这样的哈希:

00100110101110100011111000100010010101011001000001110000111001011100110101001101111010100010001011001011000110000100110101101

00001001110010000000011000001000110010001010000101010000001100000100100011100100110010100000010000000110001001010110000010001

10001110101100000100101010000010010001011010001000000000101000101100001100100000110011000000011001000000000110000000100110000

现在,如何比较这 3 个哈希值?我知道我必须将它们分成块但没有确切的方法?

我想要做的是输出所有重复文档(> 70%)及其ID和重复文档的ID。

有人可以帮忙吗?

4

2 回答 2

8

在我回答你的问题之前,重要的是要记住:

  1. Simhash 很有用,因为它可以检测附近的重复项。这意味着接近重复的结果将具有相同的哈希值。
  2. 对于精确重复,您可以简单地使用任何一种方式,一致的散列机制(例如 md5)
  3. 您在此处粘贴的示例太小,考虑到它们的大小,它们的差异很大。该算法适用于大型 Web 文档而不是小句子。

现在,我已经回复了您在此处提出的关于 Github 问题的问题。

不过,作为参考,这里有一些示例代码,您可以在对它们进行哈希处理后打印最终的近乎重复的文档。

# assuming that you have a dictionary with document id as the key and the document as the value: 
# documents = { doc_id: doc } you can do:

from simhash import simhash

def split_hash(str, num):
    return [ str[start:start+num] for start in range(0, len(str), num) ]

hashes = {}
for doc_id, doc in documents.items():
    hash = simhash(doc)

    # you can either use the whole hash for higher precision or split into chunks for higher recall
    hash_chunks = split_hash(hash, 4)

    for chunk in hash_chunks:
        if chunk not in hashes:
            hashes[chunk] = []
        hashes[chunk].append(doc_id)

# now you can print the duplicate documents:
for hash, doc_list in hashes:
    if doc_list > 1:
        print("Duplicates documents: ", doc_list)

如果有不清楚的地方,请告诉我。

于 2018-04-14T11:59:12.130 回答
2

根据备忘录的回答,如果要检测 >=70% 的相似性,则不能使用 simhash。Simhash 只允许检测非常小的汉明距离,最多可以检测到大约 6 或 7 位的差异,具体取决于您的语料库的大小。对于 70% 的相似性,您必须允许 19 位差异,这在任何正常情况下都是不可能的。您应该改为研究 minhash。

如果您有兴趣,这里有 simhash 的详细解释

于 2019-08-06T14:32:43.830 回答