使用simhash算法对网页去重

Simhash是一种用于海量文本去重的算法,它将文档转换为64位签名值,通过比较签名值的差异判断文档是否相似。与传统哈希算法不同,Simhash能反映文本内容的相似程度。通过将文档特征映射为二进制,结合权重,再转换为64位二进制值,最后通过计算海明距离确定文档的相似性。在处理大量文档时,通过分块并利用哈希查找方法可以高效地找出相似文档。
摘要由CSDN通过智能技术生成

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

1. 原理:

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

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

simhash和传统的hash都可以将文档转换为一个签名值,它们有什么不同呢?
simhash基于局部敏感哈希框架,即如果两个文档内容越相似,则其对应的两个哈希值也越接近,所以就可以将文本内容相似性问题转换为哈希值的相近性问题。
而传统的hash算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法。产生的两个签名,如果相等,说明原始内容在一定概率下是相等的;如果不相等,除了说明原始内容不相等外,不再提供任何信息,因为即使原始内容只相差一个字节,所产生的签名也很可能差别极大。而simhash的签名值除了提供原始内容是否相等的信息外,还能额外提供不相等的原始内容的差异程度的信息。

3. simhash算法步骤描述:

simhash算法步骤见下图:
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值。

4. 利用simhash对文档去重

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

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位不同,则判定为近似重复文档。

5. simhash的c++实现:

1)https://github.com/yanyiwu/simhash (读过)
2)https://github.com/seomoz/simhash-cpp (未读)
两者将字符串hash为64位数都是使用jenkins hash

6. 处理海量文档

1)利用hash查找海量simhash(一)
海量的网页经过上述步骤,转换为海量的二进制数值,此时如果新抓取到一个网页,如何找出近似重复的内容呢?
一个很容易想到的方式是一一匹配,将新网页转换为64比特的二进制数值,之后和所有网页的simhash一一比较,如果两者的海明距离小于等于3,则可以认为是近似重复网页。这种方法虽然直观,但是计算量过大,所以在以亿计的网页中,实际是不太可行的。
假设我们要寻找海明距离3以内的数值,根据抽屉原理,只要我们将整个64位的二进制串划分为4块,无论如何,匹配的两个simhash之间至少有一块区域是完全相同的,所以我们可以借鉴hash查找的方法,把这一区域的数值作为key,先找到哪些simhash的key等于目标simhash的key,然后在这些simhash集合中查找那些海明距离在3以内的数值。
这就要求我们在存储simhash时,需要把key相同的simhash存储在一起。
但又因为我们无法事先得知完全相同的是哪一块区域,所以四个区域的每个区域都应该作为我们查找value的key值。
具体做法如下:
使用hash查找simhash
存储:
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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值