Detecting NearDuplicates for Web Crawling

 

Detecting Near-Duplicates for Web Crawling(转载:http://blog.csdn.net/eaglex/article/details/6297684

问题背景

在互联网中有很多的网页的内容(content)是一样的,但是他们的网页元素却不是完全相同的,因为每个域名下的网页总会有一些自己的东西,比如广告(advertisement)、导航栏、网站版权之类的东西,但是对于搜索引擎来讲,只有内容部分才是有意义的,而后面的那些虽然不同,但是对搜索结果没有任何影响,所以在判定内容是否重复的时候,应该忽视后面的部分,当新爬取的content和数据库中的某个网页的content一样的时候,就称其为Near-Duplicates,这比传统的网页比对又智能了一些,因为毕竟一模一样的网页的概率是很小的,大部分的相似网页都会存在一些细节的变化,而如何进行这种判定就是一个本文要解决的一个问题。

工作贡献:

1.证明了SimHash算法在这个问题上的实用性。

2.实现了检测一个给出的f-bit指纹和已经存在的f-bit指纹集中是否存在最大差别k个bit-positions的算法。

3.对重复检索的算法和技术进行了一些结果的研究。

利用SimHash算法来处理指纹信息

Simhash算法是一种降维技术,可以将高维向量映射为较小的指纹。

计算步骤:

1.从爬取的网页中通过常见的信息检索的方式获得一个网页的属性集合F,也可以看成是一个高维向量,以及他们的对应的权重集合W。

2.初始化一个f维的向量V,每个维度的初始值为0。

3.对每个属性s,将其hash为一个f-bit的值,如果第i个bit的值为1,则对向量V的第i维加上s的权重w,如果为0,则减去s的权重。

4.计算完所有的属性后,如果V中第i维的值为负,则即为0,反之为1。

Simhash有两个看似矛盾的性质:一个文档的指纹是所有属性的某种hash,同时相似文档的hash值应该是相似的。后面这个特性和通常的hash函数是想反的,这是Simhash的一个特点。

在得到一个网页的f-bit的指纹(这里假设是64位)后,如何能快速的发现判定其是否和已存在的指纹有最大为k(这里假设为3) bit-positions的区别?

Hamming Distance Problem

这就是一个求hamming距离的问题,考虑一个具体的实例:

我们现在有8billion个64位的指纹集合,可以计算知占用了64G的空间。对任意一个新来的指纹f,需要在毫秒级别判断出在指纹集合中是否存在某些指纹,和f只有最多3个bit-positions的差异。

一个比较现实的解决方案是:考虑以一个已经排好序的大小为2^d的随机f-bit的指纹表T,我们只关注其中最具决定性的d位。这里这个“决定性”要满足两个条件:1、这个集合有很多,也就是说d比较大;2、只有非常少的d位是相同的。也就是说这d位的相同与否基本上决定了整个f位的数据的相同与否。这里之所以使用d位,我想是和指纹的大小相关的,即假设2^d个数的文章可以用d位来区分,直观上看上去还是比较合理的。

接下来,选择d‘满足|d' - d|是一个小整数,然后在指纹集合中找和f在d’位上相同的文章,然后对这些文章判断在剩余的f-d‘位上,其和f是否存在超过3个bit-positions的差异,由于d是有决定性的,所以满足d’的文章数目也应该是很少的,所以这个过程应该是很快的。

在线查询的算法

接下来就是创建很多指纹表Ti,对每个Ti,有一个整数pi和一个在f-bit positions上的排列πi,Ti就是对已经存在的所有指纹进行排列πi得到的有序集合。对于一个指纹f和一个整数k,算法分两个步骤:

步骤1:找到Ti中所有的前pi个bit-positions和πi(F)的前pi个bit-positions相同的指纹,假设为指纹集合F

步骤2:在F中的每一个指纹,比较其是否和πi(F)有的差异不超过k个

对于第一步的算法复杂度,如果采用二分搜索的话,是O(pi)。然后坐着又提到,如果是随机化比较好的数据,采用内插搜索法也已达到对数级别,这点不是很明白。

算法应用的实例:

假设f = 64,k=3,并且我们有8billion = 2^34个数的网页指纹,d=34,可以有下面四种设计方法

1. 20个表:将64bit分为11,11,11,11,10,10六个bit块. 根据排列组合,如果想从这6个块中找3个作为leading bits的话(这样才能满足|pi-d|是个小整数),一共有C(6,3)种找法,所以需要20个表,每个表的前三块来自不同的三个块,那么pi就有11+11+11、11+11+10和11+10+10三种可能了。

2. 16个表,先将64个bit均分成4份,然后对每份,将剩余了48bit,再均分成四份,也就是16,12,12,12,12,12五部分,很明显这种组合的可能是4*4,而pi = 28。

后面还有两种类似,我就不描述了,这样的话每次先选择前pi位相同的,再看剩余中的差异是否小于3。

最后还是有一部分是压缩和分布式存储的介绍,没太看懂,就不介绍了。

这个算法认为可以找到指纹的个数(2^d)的次方数(d)的个数的bit位可以作为决定性的指纹数据,这点简洁却十分直观,有一定的启发性。当然还有一些问题并没有交代清楚,比如那个Simhash函数相关的材料没有进行介绍,即怎么把一个属性hash为1个64位的bit组,可能这个不是文章的重点吧。

原文地址:https://www.cnblogs.com/dlutxm/p/2519827.html