Simhash算法介绍和应用内容

  • Simhash算法概述
  • simhash的生成算法
  • 相似指纹查找算法
  • 压缩算法

很长时间没有更新文章了,自从工作以后,人就变得有些松散了。一个是没有明确的目标了,经常是被工作推着走;一个是刚进入工作,确实没有适应这种节奏。现在发现不可以了,从今天开始,恢复写文章,督促自己,总结自己的学习内容。
第一篇就从刚进入工作后的第一个任务开始……

Simhash算法概述

Simhash算法最早出现在2002年。但是真正出名是在2007年的Google的《Detecting Near-duplicates for web crawling》论文中,实现了一种亿万级别的网页去重算法,从此名声四起,至今,很多的搜索中依然使用这种算法进行网页的去重。
Simhash和一般的hash不同,它有两个重要的特征:

  • 一个文档的指纹是所有属性的某种hash;
  • 相似文档的hash应该是相似的;

其中第二条至关重要,因为对一般的hash,对于两个相似的语句,会有很大的hash值差别,这就造成对相似语句的去重效果不好,而simhash对相似的语句,只会有部分位数的不同,如一个64位的hash值只会有几位的变化,这种hash也被称作是局部敏感hash。

  • 证明了simhash算法对网页进行相似性判定的实用性;
  • 实现了快速检测一个给出的f-bit的指纹和已经存在的f-bit指纹集中是否存在最大差别的k个bit-position的算法;
  • 对重复检索的算法和技术进行了一些结果的总结研究

当然论文中的一些正确性的证明对实际的应用没有太大的作用,今天的重点是对simhash算法的实现方式和其实际应用中的一些关键点的说明。论文中有两个重点内容,一个是simhash算法的生成算法,一个是simhash的相似指纹的查找算法。

simhash的生成算法

Simhash生成算法的主要分为四步:

  1. 得到网页的分词的二进制和权重:众所周知网页是由很多的分词组成的,在不同的分词方法中,每一个分词都对应着一个权重,最常见的权重就是TF-IDF方法得到的权重,而通过不同的方式,可以得到一个分词的hash,具体方法可以根据不同的方法获得;
  2. 将权重和二进制“相乘”(不完全是相乘,下面会讲),得到每一个分词的“权重hash”(瞎编的词,不要纠结,懂就行);
  3. 将得到的所有分词“权重hash”相加;
  4. 使用一个类似于符号函数降维的方法得到网页的simhash;

如下所示:
1,得到不同分词的hash和权重(怎么得到文章分词,并且得到分词的hash和权重方法很多,这里就不赘述了):
分词 二进制 权重
分词1 01010101 5
分词2 01110111 3
分词3 11010101 4
2、“相乘”得到“权重hash”(不完全是相乘,1的位为权重,0的位为权重负数)
分词 序列
分词1 -5 5 -5 5 -5 5 -5 5
分词2 -3 3 3 3 -3 3 3 3
分词3 4 4 -4 4 -4 4 -4 4
3、所有分词“权重hash”相加(这个是真的相加)
相加 -4 12 -6 12 -12 12 -6 12
4、使用一种类似于sign函数的方法,所有大于0的位为1,所有小于等于0的位为0
0 1 0 1 0 1 0 1(这个就是simhash)

通过这种方法就可以将高维向量映射为指纹向量,并且将整个网页的加权特征集合映射到一个64位的fingerprint上。判断两个文章是否相似,只需要对simhash有多少位不同进行判断就可以。一般64位的阈值会设置为3,即对64位simhash只要不同的位数在3以内(汉明距离小于等于3)就判定为两个文章相似。

相似指纹查找算法

查找还需要算法?直接java一个bitcount就能解决了。
那是自然,但是面对的场景不一样了,以前在学校自己玩一玩,来个几百万数据比一比,一会就结束了,但是现在在公司,几十亿的数据量,几千万的增量,谁受得了,比不上谷歌,但是也是一个不小的负担了。自然还是要关注一下查找算法了。
下面的内容都基于一个前提条件:对64位的simhash找到和它的汉明距离小于等于3的所有已有simhash。
在论文中,查找算法主要分为三步:

  • 第一步:首先对于集合Q构建多个表T1,T2…Tt,每一个表都是采用对应的置换函数π(i)将64-bit的fingerprint中的某p(i)位序列置换换到整个序列的最前面。即每个表存储都是整个Q的fingerprint的复制置换。
  • 第二步:对于给定的F,在每个Ti中进行匹配,寻找所有前pi位与F经过π(i)置换后的前pi位相同的fingerprint。
  • 第三步:对于所有在上一步中匹配到的置换后的fingerprint,计算其是否与π(i)(F)至多有k-bit不同。

看懂没,没有,别看我,过了一段时间我自己看都忘了以前记得什么意思,为什么这么记载,主要是论文中谷歌给了四种不同的拆分方法,分别将64位simhash分割为:
1、将64位分割为 11、11、11、11、10、10位,随机选取其中两部分作为前P(i)位;
2、将64位分割为 13、13、13、13、12位,随机选取其中两部分作为前P(i)位;
3、将64位分割为 16、16、16、16位,随机选取一个部分;将剩余部分分为12、12、12、12,随机选取一部分;将这两部分作为前P(i)位;
4、将64位分割为 16、16、16、16位,随机选取其中一部分作为前P(i)位

复杂吧,确实有点复杂,不过谷歌在论文中用大量的篇幅介绍了四种分割方法,最后只证明了一件事,就是第四种分割是最好的,查询效率和空间占用都比较均衡,所以这里只重点介绍如何通过第四种分割方法实现对汉明距离小于等于3的simhash的快速查找(重点在一个“快”,“天下武功唯快不破”)
如下所示:

1、分割:将64位分割为16、16、16、16四部分(这里就用16进制表示了,二进制十六位就是十六进制四位);
1234 5678 9ABC DEF0

2、找到数据库中所有相应位置和该simhash相同的simhash值:
如:1234000000000000,0000567800000000,000000009ABC0000, 000000000000DEF0等。

这些simhash称为候选simhash,这一步是关键的一步,理解了就懂了,为什么要这么做,首先把这四个分段看作四个抽屉,而和候选simhash不同的位会出现在四个抽屉中,但是,我们现在只想要不同位小于等于3的simhash,那么,三个不同的位不论怎样分配,必定只会分在四个抽屉中的三个(如果四个都分到了,就至少有四个不同位了),所以,只需要找到所有相应位置和simhash相同的候选simhash,相似的文章就一定在这些里面。
采用这种方法就能很好的减少比较的次数,例如:
对一个一百亿的数据库,数据量是234,切割以后,每段数据长度为216
这样只要比较234/216*4=218*4=220=1048576个数据就可以了,
从百亿降低到百万级别,很大的提升了。

3、最后只要将所有候选simhash和该simhash进行比较,判断是否有汉明距离小于等于3的数据,如果有,则证明数据库中存在相似文章;

压缩算法

在论文中,谷歌还提到了一个压缩算法,用来压缩存储的时候的数据,但是因为公司实际的存储量远没有谷歌的那么夸张,就暂时没有考虑了。但是存储方法还是要讲一下,看了网上无数的同样的论文解读,应用文章,最多就关注了上面的两个内容,对压缩算法提都没有提,有的提了,指出论文中有压缩算法,那你好歹解释一下呀,一句没看懂就过去了,你这还不如不说呢。
之前因为可能需要,疯狂的找各种资料或者论文解读,OK,没有,论文中每个单词我都认识,连在一起我就看不懂了,真是有够的。正好趁这个机会和大家分享一下,如果有问题可以一起讨论:
首先先给出论文中压缩方法关键的翻译内容吧,谷歌翻译的(正好看下对自己的论文翻译怎么样,哈哈)

The main insight is that successive fingerprints share the top d bits in expectation. We exploit this fact as follows.Let h denote the position of the most-significant 1-bit in the XOR of two successive fingerprints. Thus h takes values between 0 and f-1. For a given table, we first compute the distribution of h values and then compute a Huffman code over [0; f-1] for this distribution. Next, we choose a parameter B denoting the block size. A typical value for B would be 1024 bytes. A block with B bytes has 8B bits. We scan the sorted sequence of (permuted) fingerprints in a table and populate successive blocks as follows:
主要见解是,连续的指纹共享期望中的前d位。我们利用这个事实如下:让h表示两个连续指纹的XOR中最重要的1位的位置。因此,h取介于0和f-1之间的值。对于给定的表,我们首先计算h值的分布,然后计算[0; f-1]。接下来,我们选择一个表示块大小的参数B。 B的典型值为1024字节。具有B个字节的块具有8B位。我们扫描表中(排列的)指纹的排序序列,并按以下方式填充连续的块:

The first fingerprint in the block is remembered in its entirety. This consumes 8f bits. Thereafter, Step 2 is repeated for successive fingerprints until a block is full, i.e., we cannot carry out Step 2 without needing 8B + 1 bits or more.
块中的第一个指纹将被完整记住。这消耗了8f位。此后,对连续的指纹重复步骤2,直到一个块被填满为止,即,我们需要8B + 1位或更多才能执行步骤2。

Compute the XOR of the current fingerprint with the previous fingerprint. Find the position of the most-significant 1-bit. Append the Huffman code for this bit-position to the block. Then append the bits to the right of the most-significant 1-bit to the block.
计算当前指纹与先前指纹的XOR。找到最高有效的1位的位置。将此位位置的霍夫曼代码附加到块中。然后将最高有效1位右边的位附加到该块。

The key associated with a block is the last fingerprint that was remembered in that block. When a (permuted) fingerprint arrives, an interpolation search on the keys helps us figure out which block to decompress. Depending upon the value of pi and d, and on the distribution of fingerprints (simhash tends to cluster similar documents together), we occasionally have to decompress multiple blocks.
与一个区块关联的密钥是该区块中记住的最后一个指纹。当(排列的)指纹到达时,对键进行插值搜索可帮助我们确定要解压缩的块。根据pi和d的值以及指纹的分布(simhash倾向于将相似的文档聚在一起),有时我们需要解压缩多个块。

看懂没有,是不是一脸蒙逼,翻译的什么玩意。但是从中间隐约能感觉到一些关键内容。就是这种压缩算法是一种结合了哈夫曼编码的压缩方法。
最后的压缩形式是:一段simhash,一段哈夫曼编码,一段部分simhash编码,一段哈夫曼编码,一段部分simhash编码……
在这个压缩算法前,有一个前提条件:就是默认所有simhash编码是一种顺序排列,且相邻的simhash编码有共同的前缀。
如现在有三个simhash编码
1111 1111 1111 1111,1111 1111 1110 0011,1111 1111 1110 0001
第一个和第二个最高不同位为12,第二个和第三个最高不同位为15(从左向右数第一个编码不同的位置)

以上就是关于simhash算法的解读和应用,后面我会尽量每周都写一篇文章,来作为每周的总结,希望自己能坚持下去。

Simhash算法介绍和应用内容相关推荐

  1. simhash算法介绍-尾部添加比较经典的实现代码,代码值得一读

    方法介绍 背景 如果某一天,面试官问你如何设计一个比较两篇文章相似度的算法?可能你会回答几个比较传统点的思路: 一种方案是先将两篇文章分别进行分词,得到一系列特征向量,然后计算特征向量之间的距离(可以 ...

  2. 文本相似度计算——Simhash算法(python实现)

    互联网网页存在着大量重复内容,必须有一套高效的去重算法,否则爬虫将做非常多的无用功,工作时效性无法得到保证,更重要的是用户体验也不好.业界关于文本指纹去重的算法众多,如 k-shingle 算法.go ...

  3. 【python 走进NLP】simhash 算法计算两篇文章相似度

    互联网网页存在大量的重复内容网页,无论对于搜索引擎的网页去重和过滤.新闻小说等内容网站的内容反盗版和追踪,还是社交媒体等文本去重和聚类,都需要对网页或者文本进行去重和过滤.最简单的文本相似性计算方法可 ...

  4. 彻底弄懂LSH之simHash算法

    马克·吐温曾经说过,所谓经典小说,就是指很多人希望读过,但很少人真正花时间去读的小说.这种说法同样适用于"经典"的计算机书籍. 最近一直在看LSH,不过由于matlab基础比较差, ...

  5. SimHash算法原理与应用(Java版)

    引言 项目中原使用的文本对比算法是使用MD5 Hash的方法.MD5 Hash算法简单来说是指对于任何长度的文本都可生成一段128bit长度的字符串,相同文本生成的Hash字符串是相同的,因此可用来比 ...

  6. R语言︱文本挖掘——jiabaR包与分词向量化的simhash算法(与word2vec简单比较)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- <数据挖掘之道>摘录话语:虽然我比 ...

  7. AI一分钟 | 教育部公布高中新课标,编程、算法思维成必修内容;李彦宏否认百度会“All in AI”

    一分钟AI 李彦宏表示自己做事一向留有余地,否认百度会"All in AI". 教育部发布最新高中课程改革方案,对学生在编程.算法.人工智能和开源硬件方面的要求大幅度提升. 罗永浩 ...

  8. 3.TF-IDF算法介绍、应用、NLTK实现TF-IDF算法、Sklearn实现TF-IDF算法、算法的不足、算法改进

    3.TF-IDF 3.1.TF-IDF算法介绍 3.2.TF-IDF应用 3.3.NLTK实现TF-IDF算法 3.4.Sklearn实现TF-IDF算法 3.5.Jieba实现TF-IDF算法 3. ...

  9. 分布式块存储QoS限速算法介绍与实践以及对上层应用的影响

    分布式块存储QoS限速算法以及对上层应用的影响 QoS限速算法介绍 令牌桶 Token Bucket 漏桶 Leaky Bucket Leaky bucket as a meter Leaky buc ...

  10. 在线机器学习FTRL(Follow-the-regularized-Leader)算法介绍

    现在特别是像做在线学习和CTR这块,应用LR是最广泛的.但是批量处理超大规模的数据集和在线数据流时就遇到了问题,FTRL就是google在这样的背景下研发出来的.在处理非光滑正则化项的凸优化问题上性能 ...

最新文章

  1. Rhel6.0部署Oracle10g报错相关问题记录
  2. 动软发布微信营销服务系统,微信商城系统!
  3. error RC2108: expected numerical dialog constant
  4. java中mq组建是什么_Java教程之RabbitMQ介绍
  5. javaScript变量、作用域链
  6. WebAPI(part2)--获取元素
  7. 编写Maven插件的提示
  8. 宏观经济学gdp计算方法_宏观经济学考研的重要考点
  9. 非空验证 win窗体控件
  10. HTML5托拽上传(XMLHttpRequest和Google Gears)
  11. 8分频verilog线_解密POE交换机供电秘密,8芯网线断芯不再害怕!
  12. 微信公众号 语音转文字api_快速上手——微信公众号开发接入
  13. ppt设置外观样式_ppt怎么设置幻灯片的背景一样?
  14. 计算机二级C语言知识点复习资料,精简版
  15. 【NOI2018】你的名字(后缀自动机,线段树合并)
  16. 【AutoLeaders】一些好用的网站
  17. STIPC-003_编程挑战系列赛第三场(柯柯的期末祝福) _F.小柯来放水
  18. protel 二极管正负极怎么看
  19. SVG公众号排版 | 快速解决视频号美化出现“点赞信息”
  20. 18_一文总结Flask语法

热门文章

  1. hdmi接口和计算机连接,hdmi接口,手把手教你hdmi接口怎么连接电视
  2. 数学期望方差 expectationvariance
  3. Kibana:为 Dashboard 创建链接 drilldown - 7.11 版本
  4. oracel vm 安装windows server 2012报错Error 0x000000C4
  5. RESULT:0x80029C4A (TYPE_E_CANTLOADLIBRARY))
  6. 鲲鹏920的服务器芯片,鲲鹏920芯片是什么芯片
  7. 区块链掀起的认知革命!|筱静观察
  8. matlab 正态分布分位点,为标准正态分布的上a分位点.PPT
  9. 怎样压缩ppt的大小?
  10. 小程序18问,3分钟快速了解小程序