使用simhash算法对网页去重

本文转载自:http://www.lai18.com/content/2095944.html

如果搜索文档有很多重复的文本,比如一些文档是转载的其他的文档,只是布局不同,那么就需要把重复的文档去掉,一方面节省存储空间,一方面节省搜索时间,当然搜索质量也会提高。 

simhash是google用来处理海量文本去重的算法。

[b]1. 原理:[/b]

simhash将一个文档转换成一个64位的字节,暂且称之为签名值,然后判断两篇文档的签名值的距离是不是小于等于n(根据经验这个n一般取值为3),就可以判断两个文档是否相似。

[b]2. simhash和传统的hash算法有什么不同?[/b]

simhash和传统的hash都可以将文档转换为一个签名值,它们有什么不同呢? 

simhash基于局部敏感哈希框架,即如果两个文档内容越相似,则其对应的两个哈希值也越接近,所以就可以将文本内容相似性问题转换为哈希值的相近性问题。 

而传统的hash算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法。产生的两个签名,如果相等,说明原始内容在一定概率下是相等的;如果不相等,除了说明原始内容不相等外,不再提供任何信息,因为即使原始内容只相差一个字节,所产生的签名也很可能差别极大。而simhash的签名值除了提供原始内容是否相等的信息外,还能额外提供不相等的原始内容的差异程度的信息。

[b]3. simhash算法步骤描述:[/b]

simhash算法步骤见下图: 




1)首先从文档内容中抽取n个能表征文档的特征,至于具体实现,则可以采用不同的抽取方法,经过此步骤,获得文档的特征词及其权值对,即图中的n个(feature,weight)。方法之一可以参考 使用向量空间模型(df-idf)计算搜索文档与查询词的相关性中的(6)使用TF*IDF框架提取文档和用户查询的特征词及其权重。 

2)利用一个哈希函数将每个特征词映射成bit_count位的二进制数值。图中所示算法将每个特征词转换为了bit_count=6的二进制数值,这样每个(feature,weight)就转换为图中的(hash,weight)了。 

3)利用权重改写特征的二进制hash值,将权重融入其中,将bit_count位的二进制数值改写为bit_count个实数,形成一个实数向量。假设某个特征的权值是w,则对二进制向量做如下改写:如果二进制的某个比特位是数值1,则实数向量中对应位置改写为数值w;如果比特位数值为0,则实数向量中对应位置改写为数值-w,即权值的负数。通过以上规则,就将bit_count的二进制数改为了特征权重的实数向量。 

4)当n个特征都进行了上述改写后,对所有特征的实数向量累加获得一个代表文档整体的实数向量。累加规则也很简单,就是将对应位置的数值累加即可。 

5)再次将实数向量转换为bit_count位的二进制数值。转换规则如下:如果对应位置的数值大于0,则设置为二进制数字1;如果小于等于0,则设置为二进制数字0。如此就得到了文档的信息指纹,即最终的simhash值。 

上图将文档特征词hash为6位的二进制数值,在实际计算中,往往会将长度设定为64,即每个文档转换为64比特的simhash值。

[b]4. 利用simhash对文档去重[/b]

将文档转换为simhash值后,如何利用simhash值比较两个文档的相似性呢?对于两个文档A和B,其内容相似性可以通过比较simhash值的差异来体现,内容越相似,则二进制数值对应位置的相同的0或者1越多,两个二进制数值不同的二进制位数称为“海明距离”(也就是两个二进制数值xor 后二进制中1的个数)。 

举例如下:

[code]A = 100111;
B = 101010;
hamming_distance(A, B) = count_1(A xor B) = count_1(001101) = 3;


当我们算出所有文档的simhash值之后,需要计算文档 A和文档 B之间是否相似的条件是:
A和B的海明距离是否小于等于n
。 

一般对于64位二进制数来说,判断两个文档是否近似重复的标准是:海明距离是否小于等于3,如果两个文档的二进制数值小于等于3位不同,则判定为近似重复文档。

[b]5. simhash的c++实现: [/b]

1) https://github.com/yanyiwu/simhash  (读过) 

2) https://github.com/seomoz/simhash-cpp  (未读) 

两者将字符串hash为64位数都是使用
jenkins hash


[b]6. 处理海量文档 [/b]

1)利用hash查找海量simhash(一)  

海量的网页经过上述步骤,转换为海量的二进制数值,此时如果新抓取到一个网页,如何找出近似重复的内容呢? 

一个很容易想到的方式是一一匹配,将新网页转换为64比特的二进制数值,之后和所有网页的simhash一一比较,如果两者的海明距离小于等于3,则可以认为是近似重复网页。这种方法虽然直观,但是计算量过大,所以在以亿计的网页中,实际是不太可行的。 

假设我们要寻找海明距离3以内的数值,根据抽屉原理,只要我们将整个64位的二进制串划分为4块,无论如何,匹配的两个simhash之间至少有一块区域是完全相同的,所以我们可以借鉴hash查找的方法,把这一区域的数值作为key,先找到哪些simhash的key等于目标simhash的key,然后在这些simhash集合中查找那些海明距离在3以内的数值。 

这就要求我们在存储simhash时,需要把key相同的simhash存储在一起。 

但又因为我们无法事先得知完全相同的是哪一块区域,所以四个区域的每个区域都应该作为我们查找value的key值。 

具体做法如下: 




存储: 

1)将64位的simhash code平均分成4个区域,每个区域都有16bit。(图上红色的16位) 

2)分别以4个16位二进制码作为key,查找该key对应位置上是否有元素。(放大后的16位) 

3)对应位置没有元素,直接追加到链表上;对应位置有则直接追加到链表尾端。(图上的 S1 — SN) 

查找: 

1)将需要比较的simhash code拆分成4个16位的二进制码。 

2)分别以4个16位二进制码作为key,查找simhash集合每个key对应位置上是否有元素。 

3)如果有元素,则把链表拿出来顺序查找比较,查找那些海明距离小于3的数值,整个过程完成。 

2)空间和时间开销(一)  

这种方法,由于每个hashcode最多有4个key(显然如果有两个区域的code值相同,则key小于4个),每个key都要存储一遍,所以需要的空间是原来的4倍。但每个key对应的simhash平均数量变为simhash数量总和的1/2161/2^{16},所以搜索时间是一一搜索的4216\frac{4}{2^{16}}。 

3)利用hash查找海量simhash(二)  

假设我们还是要寻找海明距离3以内的数值,如果我们要把4个区域变成5个区域,所花的空间和时间又变成多少呢? 

因为根据抽屉原理,如果分成5个区域,则至少有两个区域是完全相同的,所以需要将这两块区域的值作为key,查找时先找到哪些simhash的key等于目标simhash的key,然后在这些simhash集合中查找那些海明距离在3以内的数值。 

究竟是哪两块区域相同共有C25C_5^2=10种情况,所以两个区域组成的这10个key都应该作为我们查找value的key值。 

具体做法如下: 

存储: 

1)将64位的simhash code分成5个区域,每个区域分别有13 13 13 13 12位。 

2)分别以10种26位(13+13)或25位(13+12)二进制码作为key,查找该key对应位置上是否有元素 

3)对应位置没有元素,直接追加到链表上;对应位置有则直接追加到链表尾端 

查找: 

1)将需要比较的simhash code分成5个区域,每个区域分别有13 13 13 13 12位。 

2)分别以10种26位(13+13)或25位(13+12)二进制码作为key,查找simhash集合对应key位置上是否有元素。 

3)如果有元素,则把链表拿出来顺序查找比较,查找那些海明距离小于3的数值,整个过程完成。 

4)空间和时间开销(二)  

这种方法,由于每个hashcode最多有10个key,每个key都要存储一遍,所以需要的空间是原来的10倍。但每个key对应的simhash平均数量为simhash数量总和的1226\frac{1}{2^{26}}或1225\frac{1}{2^{25}},所以搜索时间是一一搜索的10226\frac{10}{2^{26}}或10225\frac{10}{2^{25}}。

[b]7. 存储simhash的数据结构: [/b]

根据6,存储simhash需要用的数据结构应该为:hash < int,vector < uint_64>>吧。

[b]8. 参考: [/b]

1)《这就是搜索引擎–核心技术详解10.4》 

2) 《simhash算法原理及实现》  

3) 《海量数据相似度计算之simhash短文本查找》  

4) 《我的数学之美系列二 —— simhash与重复信息识别》  

5)google发布的simhash论文: 《Detecting near-duplicates for web crawling》  

6)google讲解simhash的ppt《Detecting Near-Duplicates for Web Crawling》 

7) 《Simhash算法原理和网页查重应用》

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值