Simhash学习笔记

simhash学习过程中的笔记

文档如果直接使用MD5做hash这种方式进行去重操作,对于一些相似文档的处理就无能为力了,简单的一个字符的变化,hash值就会发生变化,Simhash简单来说就是类似文档所产生的hash值也是类似的,这样一来就可以通过计算hash值的相似度来进行文档相似度的计算。

近来看书的时候看到了如何计算文档相似度的章节,提到了simhash,正好解决了前一段时间对于文档相似度检查的疑惑,本人基础不牢靠,在学习过程中遇到了写问题,记录下来,以便于将来进行梳理。

参考转载:simhash的总结

传统的Hash : 比如md5,其设计的目的是为了让整个分布尽可能地均匀,输入内容哪怕只有轻微变化,hash就会发生很大地变化
理想的hash :hashcode的相似程度要能直接反映输入内容的相似程度.

汉明距离:是以理查德·卫斯里·汉明的名字命名的。在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数.

过程参考
这里写图片描述

Charikar在论文中阐述的,64位simhash,海明距离在3以内的文本都可以认为是近重复文本。当然,具体数值需要结合具体业务以及经验值来确定。

SimHash :传统的hash算法是无法通过hash后的值来判断两个文本之间到底有多少相似的地方,传统的hash算法是用来对唯一性进行判断的,而simhash,相似的文本计算出来相似的simhash值也是相似的,只有个别的位数上的01值是不同的。

“你妈妈喊你回家吃饭哦,回家罗回家罗” 和 “你妈妈叫你回家吃饭啦,回家罗回家罗”。

通过simhash计算结果为:

1000010010101101111111100000101011010001001111100001001011001011

1000010010101101011111100000101011010001001111100001101010001011

通过 hashcode计算为:

1111111111111111111111111111111110001000001100110100111011011110

1010010001111111110010110011101

大家可以看得出来,相似的文本只有部分 01 串变化了,而普通的hashcode却不能做到,这个就是局部敏感哈希的魅力。目前Broder提出的shingling算法和Charikar的simhash算法应该算是业界公认比较好的算法。在simhash的发明人Charikar的论文中并没有给出具体的simhash算法和证明,“量子图灵”得出的证明simhash是由随机超平面hash算法演变而来的。

这样一来我们的文本就变成了一个定长的simhash代码,通过判断两个hash串之间的汉明距离的大小,就可以判断出两个文本之间的相似度,对于二进制字符串的a和b,海明距离为等于在a XOR b运算结果中1的个数(普遍算法)。

为什么通过汉明距离 可以推算出文本的相似度?
1:simhash本身还是一个hash算法,只不过做了部分改良,hash本身就是将不固定长度是输入通过hash映射到一个固定的长度上 ,将文本数据规则化。
2:Simhash算法的步骤
simhash经历了 分词 –> hash –> 合并 —> 降维 这些步骤,是的其相似的文本具有相似的hash值。
simhash与汉明距离

数据量大了以后怎么办

在学习这个算法的时候,都会提到数据量大了以后该怎么办。一旦我们写出来基于simhash的计算汉明距离的算法,接下来就是在现实生活中的使用场景。
如果数据量少了,将被查询的结果集加载到内存中,数据进行判断的时候,逐个进行判断,一旦发现小于等于3的,返回false。但是如果数据量大了,这样是算法就会变的很慢。参考了很多文章,看的也是一知半解,本人比较笨,只能多看几遍,慢慢的理解了其中的思路。 simhash海量数据结构思路,这边文章感觉结合java的hashmap的思路我感觉很新鲜,对我理解simhash的帮助很大。

抽屉原理 :桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果。这一现象就是我们所说的“抽屉原理”。 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素。” 抽屉原理有时也被称为鸽巢原理。它是组合数学中一个重要的原理

汉明距离=3 ,64位二进制数字。
只要我们将整个64位的二进制串划分为4块,无论如何,匹配的两个simhash code之间至少有一块区域是完全相同的。
基于这个原理,现在可以讲原有的64位的二进制数据分成了四份,按照位置数 1-16,16-32,33-48,48-64.
这样一来的话,同一个64位的二进制数据经过组合就分成了4份儿,四份儿数据的前16位一定是精确的,被查询的数组如果前16位精确匹配上,那么只需要计算后面48位的的汉明距离是否有小于3的,这样一来的话,就大大减少了需要查询的数据量。

我们需要存储4份table,并将64位的simhash code等分成4份;对于每一个输入的code,我们通过精确匹配的方式,查找前16位相同的记录作为候选记录,如下图所示:

这里写图片描述

让我们来总结一下上述算法的实质:
1、将64位的二进制串等分成四块
2、调整上述64位二进制,将任意一块作为前16位,总共有四种组合,生成四份table
3、采用精确匹配的方式查找前16位
4、如果样本库中存有2^34(差不多10亿)的哈希指纹,则每个table返回2^(34-16)=262144个候选结果,大大减少了海明距离的计算成本

我们可以将这种方法拓展成多种配置,不过,请记住,table的数量与每个table返回的结果呈此消彼长的关系,也就是说,时间效率与空间效率不可兼得,参看下图:

这里写图片描述

事实上,这就是Google每天所做的,用来识别获取的网页是否与它庞大的、数以十亿计的网页库是否重复。另外,simhash还可以用于信息聚类、文件压缩等.

simhash 之hashmap

提高查询效率归根结底就是提高查询的效率,hashmap号称最快的数据结构,可以参考hashmap的实现原理来实现simhash

如果我们需要得到key对应的value,需要经过这些计算,传入key,计算key的hashcode,得到7的位置;发现7位置对应的value还有好几个,就通过链表查找,直到找到v72。其实通过这么分析,如果我们的hashcode设置的不够好,hashmap的效率也不见得高。借鉴这个算法,来设计我们的simhash查找。通过顺序查找肯定是不行的,能否像hashmap一样先通过键值对的方式减少顺序比较的次数。看下图:
这里写图片描述
大规模simhash算法优化
存储:
1、将一个64位的simhash code拆分成4个16位的二进制码。(图上红色的16位)
2、分别拿着4个16位二进制码查找当前对应位置上是否有元素。(放大后的16位)
3、对应位置没有元素,直接追加到链表上;对应位置有则直接追加到链表尾端。(图上的 S1 — SN)

查找:
1、将需要比较的simhash code拆分成4个16位的二进制码。
2、分别拿着4个16位二进制码每一个去查找simhash集合对应位置上是否有元素。
2、如果有元素,则把链表拿出来顺序查找比较,直到simhash小于一定大小的值,整个过程完成。

原理:
借鉴hashmap算法找出可以hash的key值,因为我们使用的simhash是局部敏感哈希,这个算法的特点是只要相似的字符串只有个别的位数是有差别变化。那这样我们可以推断两个相似的文本,至少有16位的simhash是一样的。具体选择16位、8位、4位,大家根据自己的数据测试选择,虽然比较的位数越小越精准,但是空间会变大。分为4个16位段的存储空间是单独simhash存储空间的4倍。之前算出5000w数据是 382 Mb,扩大4倍1.5G左右,还可以接受:)

通过这样计算,我们的simhash查找过程全部降到了1毫秒以下。就加了一个hash效果这么厉害?我们可以算一下,原来是5000w次顺序比较,现在是少了2的16次方比较,前面16位变成了hash查找。后面的顺序比较的个数是多少? 2^16 = 65536, 5000w/65536 = 763 次。。。。实际最后链表比较的数据也才 763次!所以效率大大提高!

太经典了!!!

总结

理论跟实际之间总是存在差距,理论联系实际就是一个相互妥协的过程,海量数据中simhash的应用根本上就是时间维度跟空间维度上的一个相互协调的过程。笔记写的很乱,几篇参考的博客写的还是很经典的。

参考博客:
simhash与重复信息识别
海量数据相似度计算之simhash和海明距离

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值