zoukankan      html  css  js  c++  java
  • 基于simhash的文本去重原理

    互联网网页存在大量的内容重复的网页, 文本,无论对于搜索引擎,爬虫的网页去重和过滤、新闻小说等内容网站的内容反盗版和追踪,还是社交媒体等文本去重和聚类,都需要对网页或者文本进行去重和过滤。为此必须有一套高效的去重算法,要不然爬虫将做非常多的无用功,时效性等都无法得到保证,更重要的是用户体验也不好。业界关于文本指纹去重的算法众多,如 k-shingle 算法、google 提出的simhash 算法、Minhash 算法、百度top k 最长句子签名算法等等,下面介绍下simhash算法以及python应用。

    1. simhash 与传统hash 的区别

    simhash 是 google 用来处理海量文本去重的算法。 simhash 可以将一个文档转换成一个 64 位的字节,暂且称之为特征字。判断文档是否重复,只需要判断文档特征字之间的汉明距离。根据经验,一般当两个文档特征字之间的汉明距离小于 3, 就可以判定两个文档相似。

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

    我们主要解决的是文本相似度计算,要比较的是两个文章是否相识,当然我们降维生成了hash签名也是用于这个目的。看到这里估计大家就明白了,我们使用的simhash就算把文章中的字符串变成 01 串也还是可以用于计算相似度的,而传统的hash却不行。我们可以来做个测试,两个相差只有一个字符的文本串,“你妈妈喊你回家吃饭哦” 和 “你妈妈叫你回家吃饭啦”。

    通过simhash计算结果为:

    1000010010101101111111100000101011010001001111100001001011001011

     1000010010101101011111100000101011010001001111100001101010001011

    通过传统hash计算为:

    0001000001100110100111011011110

    1010010001111111110010110011101

    大家可以看得出来,相似的文本只有部分 01 串变化了,而普通的hash却不能做到,这个就是局部敏感哈希的魅力。

    2. simhash实现的主要步骤

    在新拿到文本之后需要先进行分词,这是因为需要挑出TopN个词来表征这篇文本,并且分词的权重不一样,可以使用相应数据集的tf-idf值作为分词的权重,这样就分成了带权重的分词结果。

    之后对所有分词进行哈希运算获取二值化的hash结果,再将权重与哈希值相乘,获得带权重的哈希值,最后进行累加以及二值化处理。

    2.1 分词

    使用分词手段将文本分割成关键词的特征向量,分词方法有很多一般都是实词,也就是把停用词等都去掉之后的部分,使用者可以根据自己的需求选择.最后形成去掉噪音词的单词序列并为每个词加上权重. 例如:

    行者AI 专注 于 游戏 领域 多年 AI技术 积淀 一站式 提供 文本 图片 音视频 内容 审核 游戏AI 以及 数据 平台 服务
    

    目前的词只是进行了分割,但是词与词含有的信息量是不一样的,比如行者AI 游戏 审核 这三个词就比 专注 服务 以及更能表达文本的主旨含义,这也就是所谓信息熵的概念。

    为此我们还需要设定特征词的权重,简单一点的可以使用绝对词频来表示,也就是某个关键词出现的次数,但是事实上出现次数少的所含有的信息量可能更多.总之需要选择一种加权方法,否则效果会打折扣。

    2.2 哈希和权重化

    前面我们使用分词方法和权重分配将文本就分割成若干个带权重的实词,比如权重使用1-5的数字表示,1最低5最高。

    行者AI(5) 专注(2) 于(1) 游戏(3) 领域(1) 多年(1) AI技术(4) 积淀(1) 一站式(2) 提供(1) 文本(2) 图片(2) 音视频(2) 内容(1) 审核(2) 游戏AI(4) 以及(1) 数据(3) 平台(1) 服务(2)
    

    对各个特征词进行二值化哈希值计算, 再将所有的哈希值累加,最后将累加结果二值化。

    2.3 汉明距离

    在信息论中,两个等长字符串之间的汉明距离(英语:Hamming distance)是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数。

    汉明重量是字符串相对于同样长度的零字符串的汉明距离,也就是说,它是字符串中非零的元素个数:对于二进制字符串来说,就是1的个数,所以11101的汉明重量是4。

    对于二进制字符串a与b来说,它等于a 异或b后所得二进制字符串中“1”的个数。

    汉明距离是以理查德·卫斯里·汉明的名字命名的,汉明在误差检测与校正码的基础性论文中首次引入这个概念。

    在通信中累计定长二进制字中发生翻转的错误数据位,所以它也被称为信号距离。汉明重量分析在包括信息论、编码理论、密码学等领域都有应用。但是,如果要比较两个不同长度的字符串,不仅要进行替换,而且要进行插入与删除的运算,在这种场合下,通常使用更加复杂的编辑距离等算法。

    谷歌经过工程验证认为当两个64bit的二值化simhash值的汉明距离超过3则认为不相似,所以判重问题就转换为求两个哈希值的汉明距离问题。

    3. python 实现

    pip 源中有数种 simhash 的实现,simhash,使用起来十分方便,直接使用 pip 就可以安装

    pip install simhash
    

    使用例子

    from simhash import Simhash
    
    
    def simhash_demo(text1, text2):
    """
    求两文本的相似度
    :param text1:
    :param text2:
    :return:
    """
    a_simhash = Simhash(text1)
    b_simhash = Simhash(text2)
    max_hashbit = max(len(bin(a_simhash.value)), (len(bin(b_simhash.value))))
    # 汉明距离
    distince = a_simhash.distance(b_simhash)
    print(distince)
    similar = 1 - distince / max_hashbit
    return similar
    
    
    if __name__ == '__main__':
    text1 = "行者AI专注于游戏领域,多年的AI技术积淀,一站式提供文本、图片、音/视频内容审核,游戏AI以及数据平台服务"
    
    text2 = "行者AI专注于游戏领域,多年的AI技术积淀,二站式提供文本、图片、音 视频内容审核,游戏AI以及数据平台服务"
    
    similar = simhash_demo(text1, text2)
    print(similar)
    
    

    PS:

    我们是行者AI,我们在“AI+游戏”中不断前行。

    如果你也对游戏感兴趣,对AI充满好奇,那就快来加入我们(hr@xingzhe.ai)。

  • 相关阅读:
    calico网络异常,不健康
    k8s部署xxl-job-admin
    K8S
    二进制部署k8s高可用
    kubernetes集群部署redis5.0.6单机版
    K8s之MySQL实现数据持久化
    Kubernetes网络
    Oracle数据表锁死的解决办法
    查询各个表的详情
    Oracle-查看所有表、字段以及表注释和字段注释
  • 原文地址:https://www.cnblogs.com/xingzheai/p/14139921.html
Copyright © 2011-2022 走看看