首页IT科技java hmacsha算法(Simhash算法原理和网页查重应用)

java hmacsha算法(Simhash算法原理和网页查重应用)

时间2025-06-20 15:04:11分类IT科技浏览6016
导读:传统的hash算法只负责将原始内容尽量均匀随机地映射为一个签名值,原理上相当于伪随机数产生算法。产生的两个签名,如果相等,说明原始内容在一定概率下是相等的;如果不相等,除了说明原始内容不相等外,不再提供任何信息,因为即使原始内容只相差一个字节,所产生的签名也很可能差别极大。从这个意义上来说,要设计一个h...

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

而Google的simhash算法产生的签名,可以用来比较原始内容的相似度时                    ,便很想了解这种神奇的算法的原理       。出人意料                   ,这个算法并不深奥,其思想是非常清澈美妙的                    。

Simhash算法

simhash算法的输入是一个向量              ,输出是一个f位的签名值             。为了陈述方便                   ,假设输入的是一个文档的特征集合      ,每个特征有一定的权重       。比如特征可以是文档中的词              ,其权重可以是这个词出现的次数                    。simhash算法如下:

1                    ,将一个f维的向量V初始化为0;f位的二进制数S初始化为0;

2      ,对每一个特征:用传统的hash算法对该特征产生一个f位的签名b             。对i=1到f:

如果b的第i位为1       ,则V的第i个元素加上该特征的权重;

否则                    ,V的第i个元素减去该特征的权重。

3             ,如果V的第i个元素大于0       ,则S的第i位为1                    ,否则为0;

4             ,输出S作为签名                    。

算法几何意义和原理

这个算法的几何意义非常明了                    。它首先将每一个特征映射为f维空间的一个向量,这个映射规则具体是怎样并不重要                    ,只要对很多不同的特征来说                   ,它们对所对应的向量是均匀随机分布的,并且对相同的特征来说对应的向量是唯一的就行。比如一个特征的4位hash签名的二进制表示为1010              ,那么这个特征对应的

4维向量就是(1, -1, 1,

-1)T                   ,即hash签名的某一位为1      ,映射到的向量的对应位就为1              ,否则为-1             。然后                    ,将一个文档中所包含的各个特征对应的向量加权求和      ,加权的系数等于该特征的权重                    。得到的和向量即表征了这个文档       ,我们可以用向量之间的夹角来衡量对应文档之间的相似度      。最后                    ,为了得到一个f位的签名             ,需要进一步将其压缩       ,如果和向量的某一维大于0                    ,则最终签名的对应位为1             ,否则为0             。这样的压缩相当于只留下了和向量所在的象限这个信息,而64位的签名可以表示多达264个象限                    ,因此只保存所在象限的信息也足够表征一个文档了                    。

明确了算法了几何意义                   ,使这个算法直观上看来是合理的      。但是,为何最终得到的签名相近的程度              ,可以衡量原始文档的相似程度呢?这需要一个清晰的思路和证明       。在simhash的发明人Charikar的论文中[2]并没有给出具体的simhash算法和证明                   ,以下列出我自己得出的证明思路                    。

Simhash是由随机超平面hash算法演变而来的      ,随机超平面hash算法非常简单              ,对于一个n维向量v                    ,要得到一个f位的签名(f<<n)      ,算法如下:

1       ,随机产生f个n维的向量r1,…rf;

2                    ,对每一个向量ri             ,如果v与ri的点积大于0       ,则最终签名的第i位为1                    ,否则为0.

这个算法相当于随机产生了f个n维超平面             ,每个超平面将向量v所在的空间一分为二,v在这个超平面上方则得到一个1                    ,否则得到一个0                   ,然后将得到的

f个0或1组合起来成为一个f维的签名             。如果两个向量u, v的夹角为θ,则一个随机超平面将它们分开的概率为θ/π              ,因此u,

v的签名的对应位不同的概率等于θ/π       。所以                   ,我们可以用两个向量的签名的不同的对应位的数量      ,即汉明距离              ,来衡量这两个向量的差异程度                    。

Simhash算法与随机超平面hash是怎么联系起来的呢?在simhash算法中                    ,并没有直接产生用于分割空间的随机向量      ,而是间接产生的:第

k个特征的hash签名的第i位拿出来       ,如果为0                    ,则改为-1             ,如果为1则不变       ,作为第i个随机向量的第k维             。由于hash签名是f位的                    ,因此这样能产生

f个随机向量             ,对应f个随机超平面。下面举个例子:

假设用5个特征w1,…,w5来表示所有文档,现要得到任意文档的一个3维签名                    。假设这5个特征对应的3维向量分别为:

h(w1) = (1, -1, 1)T

h(w2) = (-1, 1, 1)T

h(w3) = (1, -1, -1)T

h(w4) = (-1, -1, 1)T

h(w5) = (1, 1, -1)T

按simhash算法                    ,要得到一个文档向量d=(w1=1, w2=2, w3=0, w4=3, w5=0)

T的签名                   ,

先要计算向量m = 1*h(w1) + 2*h(w2) + 0*h(w3) + 3*h(w4) + 0*h(w5) = (-4,

-2, 6) T,

然后根据simhash算法的步骤3              ,得到最终的签名s=001                    。

上面的计算步骤其实相当于                   ,先得到3个5维的向量      ,第1个向量由h(w1),…,h(w5)的第1维组成:

r1=(1,-1,1,-1,1) T;

第2个5维向量由h(w1),…,h(w5)的第2维组成:

r2=(-1,1,-1,-1,1) T;

同理              ,第3个5维向量为:

r3=(1,1,-1,1,-1) T.

按随机超平面算法的步骤2                    ,分别求向量d与r1,r2,r3的点积:

d T r1=-4 < 0      ,所以s1=0;

d T r2=-2 < 0       ,所以s2=0;

d T r3=6 > 0                    ,所以s3=1.

故最终的签名s=001             ,与simhash算法产生的结果是一致的。

从上面的计算过程可以看出       ,simhash算法其实与随机超平面hash算法是相同的                    ,simhash算法得到的两个签名的汉明距离             ,可以用来衡量原始向量的夹角             。这其实是一种降维技术,将高维的向量用较低维度的签名来表征                    。衡量两个内容相似度                    ,需要计算汉明距离                   ,这对给定签名查找相似内容的应用来说带来了一些计算上的困难;我想,是否存在更为理想的simhash算法              ,原始内容的差异度                   ,可以直接由签名值的代数差来表示呢?

大规模网页的近似查重

详细内容可以看WWW07的 Detecting Near-Duplicates

for Web Crawling      。

例如      ,文本的特征可以选取分词结果              ,而权重可以用df来近似             。

Simhash具有两个“冲突的性质             ”:

1. 它是一个hash方法

2. 相似的文本具有相似的hash值                    ,如果两个文本的simhash越接近      ,也就是汉明距离越小       ,文本就越相似                    。

因此海量文本中查重的任务转换位如何在海量simhash中快速确定是否存在汉明距离小的指纹      。也就是:在n个f-bit的指纹中                    ,查询汉明距离小于k的指纹       。

在文章的实验中             ,simhash采用64位的哈希函数                    。在80亿网页规模下汉明距离=3刚好合适             。

因此任务的f-bit=64 , k=3 , n= 8*10^11

任务清晰       ,首先看一下两种很直观的方法:

1.

枚举出所有汉明距离小于3的simhash指纹                    ,对每个指纹在80亿排序指纹中查询       。(这种方法需要进行C(64             ,3)=41664词的simhash指纹,再为每个进行一次查询)

2.

所有接近的指纹排序到一起                    ,这至多有41664排序可能                   ,需要庞大的空间                    。提出的方法介于两者之间,合理的空间和时间的折中             。

假设我们有一个已经排序的容量为2d              ,f-bit指纹集。看每个指纹的高d位                    。该高低位具有以下性质:尽管有很多的2d位组合存在                   ,但高d位中有只有少量重复的                    。

现在找一个接近于d的数字d’      ,由于整个表是排好序的              ,所以一趟搜索就能找出高d’位与目标指纹F相同的指纹集合f’。因为d’和d很接近                    ,所以找出的集合f’也不会很大             。

• 最后在集合f’中查找 和F之间海明距离为k的指纹也就很快了                    。

• 总的思想:先要把检索的集合缩小      ,然后在小集合中检索f-d’位的海明距离

按照例子       ,80亿网页 有2^34

个                    ,那么理论上34位就能表示完80亿不重复的指纹      。我们假设最前的34位的表示完了80亿指纹             ,假设指纹在前30位是一样的       ,那么后面4位还可以表示24个                    ,

只需要逐一比较这16个指纹是否于待测指纹汉明距离小于3             。

假设:对任意34位中的30位都可以这么做                    。

因此在一次完整的查找中             ,限定前q位精确匹配(假设这些指纹已经是q位有序的,可以采用二分查找                    ,如果指纹量非常大                   ,且分布均匀,甚至可以采用内插搜索)              ,之后的2d-q个指纹剩下64-q位需要比较汉明距离小于3      。

于是问题就转变为如何切割64位的q       。

将64位平分成若干份                   ,例如4份ABCD      ,每份16位                    。

假设这些指纹已经按A部分排序好了              ,我们先按A的16位精确匹配到一个区间                    ,这个区间的后BCD位检查汉明距离是否小于3             。

同样的假设      ,其次我们按B的16位精确匹配到另一个区间       ,这个区间的所有指纹需要在ACD位上比较汉明距离是否小于3       。

同理还有C和D

所以这里我们需要将全部的指纹T复制4份                    , T1 T2 T3 T4             , T1按A排序       ,T2按B排序…

4份可以并行进行查询                    ,最后把结果合并                    。这样即使最坏的情况:3个位分别落在其中3个区域ABC,ACD,BCD,ABD…都不会被漏掉             。

只精确匹配16位             ,还需要逐一比较的指纹量依然庞大,可能达到2d-16个                    ,我们也可以精确匹配更多的。

例如:将64位平分成4份ABCD                   ,每份16位,在BCD的48位上              ,我们再分成4份                   ,WXZY      ,每份12位              ,

汉明距离的3位可以散落在任意三块                    ,那么A与WXZY任意一份合起来做精确的28位…剩下3份用来检查汉明距离                    。

同理B      ,C       ,D也可以这样                    ,那么T需要复制16次             ,ABCD与WXYZ的组合做精确匹配       ,每次精确匹配后还需要逐一比较的个数降低到2d-28个                    。不同的组合方式也就是时间和空间上的权衡。

最坏情况是其中3份可能有1位汉明距离差异为1             。

算法的描述如下:

1)先复制原表T为Tt份:T1,T2,….Tt

2)每个Ti都关联一个pi和一个πi                    ,其中pi是一个整数, πi是一个置换函数             ,负责把pi个bit位换到高位上                    。

3)应用置换函数πi到相应的Ti表上,然后对Ti进行排序

4)然后对每一个Ti和要匹配的指纹F              、海明距离k做如下运算:

a) 然后使用F’的高pi位检索                    ,找出Ti中高pi位相同的集合

b) 在检索出的集合中比较f-pi位                   ,找出海明距离小于等于k的指纹

5)最后合并所有Ti中检索出的结果

由于文本已经压缩成8个字节了,因此其实Simhash近似查重精度并不高:

附参考文献:

[1] Detecting near-duplicates for web crawling.

[2] Similarity estimation techniques from rounding

algorithms.

[3] http://en.wikipedia.org/wiki/Locality_sensitive_hashing

[4] http://www.coolsnap.net/kevin/?p=23

[5] http://www.cnblogs.com/linecong/archive/2010/08/28/simhash.html

[6] http://blog.csdn.net/lgnlgn/article/details/6008498

博主注:本文主要就是拼接了参考文献[5][6]而成      。

声明:本站所有文章              ,如无特殊说明或标注                   ,均为本站原创发布             。任何个人或组织      ,在未征得本站同意时              ,禁止复制                   、盗用      、采集              、发布本站内容到任何网站                    、书籍等各类媒体平台                    。如若本站内容侵犯了原著者的合法权益                    ,可联系我们进行处理      。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vue鼠标悬停改变背景(Vue鼠标点击事件和键盘事件) mysql怎么恢复备份数据库文件(mysql怎么恢复备份数据库)