simhash局部敏感哈希 文章去重

  • 传统的Hash算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上仅相当于伪随机数产生算法。传统的hash算法产生的两个签名,如果原始内容在一定概率下是相等的;如果不相等,除了说明原始内容不相等外,不再提供任何信息,因为即使原始内容只相差一个字节,所产生的签名也很可能差别很大。所以传统的Hash是无法在签名的维度上来衡量原内容的相似度,而SimHash本身属于一种局部敏感哈希算法,它产生的hash签名在一定程度上可以表征原内容的相似度。

import jieba.posseg as pseg
import zlib
import jieba.analyse


def getWords(content):
    words = jieba.analyse.extract_tags(content, topK=20, withWeight=True, allowPOS=('ns', 'n', 'vn', 'v'))
    res = {}
    for word, flag in words:
        if word in res:
            res[word] = res[word] + 1
        else:
            res[word] = 1
    return res

def simHash(words):
    # print(words)
    s = [0 for i in range(0, 32)]
    for i in words:
        v = words[i]
        cksum = zlib.adler32(i.encode('utf8'))
        for k in range(0, 32):
            if (cksum >> k) & 1 == 0:
                s[k] = s[k] - v

            else:
                s[k] = s[k] + v
    res = 0
    for i in s:
        if i > 0:
            res = res | 1
        else:
            res = res | 0

        res = res << 1
    return res

def getSimHash(data):
    return simHash(getWords(data))

def getDis(hash1, hash2):
    dis = 0
    for i in range(0, 32):
        if ((hash1>>i)&1) ^ ((hash2>>i)&1) == 1:
            dis = dis + 1
    return dis

# data1 = "理解分治法的算法思想,阅读实现书上已有的部分程序代码并完善程序,加深对分治法 的算法原理及实现过程的理解。用分治法实现一组无序序列的两路合并排序和快速排序。要求清楚合并排序及快速排序 的基本原理,编程实现分别用这两种方法将输入的一组无序序列排序为有序序列后输出。"
# data2 = "弄清楚分治法的算法思想,实现书上已有的部分程序代码并且完善之,加深对分治法的算法原理及实现过程的理解。用分治法实现一组无序序列的两路合并排序和快速排序。要求搞懂合并排序及快速排序的原理,分别实现这两种方法将输入的一组无序序列排序为有序序列后输出。"
# data3 = "在北京天天安门广场,100个深蹲的训练强度不能保证适合每个人的。对于能力强的人,100个深蹲只需要一组就能完成,而且还不费力。如果他每天做100个深蹲坚持一个月的话,很可能他没有任何变化,因为这个强度对于他过低了。而相反,对于体能不好的、体重超标的、长时间不运动的、关节有伤病的人来说,这100深蹲极有可能会伤害到他们,更别提坚持一个月了"
# data4 = "首先,先来说的一个重点是因人而异原则,也就是说每个人的身体情况都不一样,100个深蹲的训练强度不能保证适合每个人的。对于能力强的人,100个深蹲只需要一组就能完成,而且还不费力。如果他每天做100个深蹲坚持一个月的话,很可能他没有任何变化,因为这个强度对于他过低了。而相反,对于体能不好的、体重超标的、长时间不运动的、关节有伤病的人来说,这100深蹲极有可能会伤害到他们,更别提坚持一个月了。"
def open_data(data_file):

    with open(data_file,'r') as f:
        content_data = f.read()
        return content_data

data1 = open_data('./data_1.txt')
hash1 = getSimHash(data1)
print("simhash for data_1: ", hash1)

data2 = open_data('./data_2.txt')
hash2 = getSimHash(data2)
print("simhash for data_2: ", hash2)

print("distance: ", getDis(hash1, hash2))

猜你喜欢

转载自blog.csdn.net/RedPintings/article/details/81103179