SimHash是什么

SimHash是Google在2007年发表的论文《Detecting Near-Duplicates for Web Crawling 》中提到的一种指纹生成算法或者叫指纹提取算法,被Google广泛应用在亿级的网页去重的Job中,作为locality sensitive hash(局部敏感哈希)的一种,其主要思想是降维,什么是降维? 举个通俗点的例子,一篇若干数量的文本内容,经过simhash降维后,可能仅仅得到一个长度为32或64位的二进制由01组成的字符串,这一点非常相似我们的身份证,试想一下,如果你要在中国13亿+的茫茫人海中寻找一个人,如果你不知道这个人的身份证,你可能要提供姓名 ,住址, 身高,体重,性别,等等维度的因素来确定是否为某个人,从这个例子已经能看出来,如果有一个一维的核心条件身份证,那么查询则是非常快速的,如果没有一维的身份证条件,可能综合其他几个非核心的维度,也能确定一个人,但是这种查询则就比较慢了,而通过我们的SimHash算法,则就像是给每个人生成了一个身份证,使复杂的事物,能够通过降维来简化。

SimHash的工作原理

SimHash算法工作流程图:
 
解释下上图:
(1)准备一篇文本
(2)过滤清洗,提取n个特征关键词,这步一般用分词的方法实现,关于分词,比较常用的有IK,mmseg4j,ansj
(3)特征加权,这一步如果有自己针对某个行业的定义的语料库时候可以使用,没有的话,就用分词后的词频即可
(4)对关键词进行hash降维01组成的签名(上述是6位)
(5)然后向量加权,对于每一个6位的签名的每一位,如果是1,hash和权重正相乘,如果为0,则hash和权重负相乘,至此就能得到每个特征值的向量。
(6)合并所有的特征向量相加,得到一个最终的向量,然后降维,对于最终的向量的每一位如果大于0则为1,否则为0,这样就能得到最终的simhash的指纹签名
 
一个例子如下:
 

SimHash的应用

通过上面的步骤,我们可以利用SimHash算法为每一个网页生成一个向量指纹,那么问题来了,如何判断2篇文本的相似性?

这里面主要应用到是海明距离。
 
(1)什么是海明距离
两个码字的对应比特取值不同的比特数称为这两个码字的海明距离。在一个有效编码集中,任意两个码字的海明距离的最小值称为该编码集的海明距离。举例如下:10101和00110从第一位开始依次有第一位、第四、第五位不同,则海明距离为3。
 
(2)海明距离的几何意义
n位的码字可以用n维空间的超立方体的一个顶点来表示。两个码字之间的海明距离就是超立方体两个顶点之间的一条边,而且是这两个顶点之间的最短距离。
 
(3)海明距离的应用场景
用于编码的检错和纠错 
 
经过SimHash算法提取来的指纹(Simhash对长文本500字+比较适用,短文本可能偏差较大,具体需要根据实际场景测试),最后使用海明距离,求相似,在google的论文给出的数据中,64位的签名,在海明距离为3的情况下,可认为两篇文档是相似的或者是重复的,当然这个值只是参考值,针对自己的应用可能又不同的测试取值
 
到这里相似度问题基本解决,但是按这个思路,在海量数据几百亿的数量下,效率问题还是没有解决的,因为数据是不断添加进来的,不可能每来一条数据,都要和全库的数据做一次比较,按照这种思路,处理速度会越来越慢,线性增长。
 
针对这个问题在Google的论文中也提出了对应的思路,根据鸽巢原理(也称抽屉原理):
 
桌上有十个苹果,要把这十个苹果放到九个抽屉里,无论怎样放,我们会发现至少会有一个抽屉里面至少放两个苹果。这一现象就是我们所说的“抽屉原理”。 抽屉原理的一般含义为:“如果每个抽屉代表一个集合,每一个苹果就可以代表一个元素,假如有n+1个元素放到n个集合中去,其中必定有一个集合里至少有两个元素。” 抽屉原理有时也被称为鸽巢原理。它是组合数学中一个重要的原理。[1]
 
道理很简单,但在把这应用到现实问题中,可是能发挥巨大作用的,这也就是数学的奥妙之处。
 
针对海量数据的去重效率,我们可以将64位指纹,切分为4份16位的数据块,根据抽屉原理在海明距离为3的情况,如果两个文档相似,那么它必有一个块的数据是相等的,如图:
然后将4份数据通过K-V数据库或倒排索引存储起来K为16位截断指纹,V为K相等时剩余的48位指纹集合,查询时候,精确匹配这个指纹的4个16位截断,如图所示:
 
如此,假设样本库,有2^34条数据(171亿数据),假设数据均匀分布,则每个16位(16个01数字随机组成的组合为2^16个)倒排返回的最大数量为
2^34/2^16=2^(34-16)=262144个候选结果,4个16位截断索引,总的结果为:4*262144=1048576,约为100多万,通过
这样一来的降维处理,原来需要比较171亿次,现在只需要比较100万次即可得到结果,这样以来大大提升了计算效率。
 
 
参考文章:

海量数据去重之SimHash算法简介和应用的更多相关文章

  1. 文本去重之SimHash算法

    文本去重之SimHash算法 - pathenon的个人页面 - 开源中国社区 文本去重之SimHash算法

  2. 网页去重之Simhash算法

    Simhash算法是Google应用在网页去重中的一个常用算法,在开始讲解Simhash之前,先了解——什么是网页去重?为什么要进行网页去重?如何进行网页去重,其基本框架是什么?   网页去重,顾名思 ...

  3. 彻底弄懂LSH之simHash算法

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

  4. simhash算法:海量千万级的数据去重

    simhash算法:海量千万级的数据去重 simhash算法及原理参考: 简单易懂讲解simhash算法 hash 哈希:https://blog.csdn.net/le_le_name/articl ...

  5. 基于局部敏感哈希的协同过滤算法之simHash算法

    搜集了快一个月的资料,虽然不完全懂,但还是先慢慢写着吧,说不定就有思路了呢. 开源的最大好处是会让作者对脏乱臭的代码有羞耻感. 当一个做推荐系统的部门开始重视[数据清理,数据标柱,效果评测,数据统计, ...

  6. (转)simhash算法原理及实现

    simhash是google用来处理海量文本去重的算法. google出品,你懂的. simhash最牛逼的一点就是将一个文档,最后转换成一个64位的字节,暂且称之为特征字,然后判断重复只需要判断他们 ...

  7. 字符串匹配算法之SimHash算法

    SimHash算法 由于实验室和互联网基本没啥关系,也就从来没有关注过数据挖掘相关的东西.在实际工作中,第一次接触到匹配和聚类等工作,虽然用一些简单的匹配算法可以做小数据的聚类,但数据量达到一定的时候 ...

  8. MLlearning(2)——simHash算法

    这篇文章主要讲simHash算法.这是一种LSH(Locality-Sensitive Hashing,局部敏感哈希)的简单实现.它是广泛用于数据去重的算法,可以用于相似网站.图片的检索.而且当两个样 ...

  9. SimHash算法

    短文本合并重复(去重)的简单有效做法 - 旁观者 - 博客园 短文本合并重复(去重)的简单有效做法 SimHash算法 - ACdreamer - 博客频道 - CSDN.NET SimHash算法

随机推荐

  1. P3272 [SCOI2011]地板

    \(\color{#0066ff}{ 题目描述 }\) lxhgww的小名叫"小L",这是因为他总是很喜欢L型的东西.小L家的客厅是一个R*C的矩形,现在他想用L型的地板来铺满整个 ...

  2. 一些优秀的Firefox扩展

    AdBlock Plus 拦截广告. 在对付CSDN等垃圾网站时非常有用. Block Site 拦截你不想看的网站 没有知乎的一天真好... XStyle 设置自己喜欢的CSS样式(表示自己并不会用 ...

  3. 树的遍历顺序 - dfs序|欧拉序|dfn序(备忘)

    (仅作备忘) dfs序是dfs过程中对于某节点进入这个节点的子树和离开子树的顺序 满足每个节点都会在dfs序上出现恰好两次 任意子树的dfs序都是连续的 欧拉序是dfs过程中经过节点的顺序 每个节点至 ...

  4. Java内存区域与内存溢出异常---运行时数据区域

    运行时数据区域 Java虚拟机所管理的内存将会包括以下几个运行时数据区域 线程私有区域 1.程序计数器   程序计数器记录的是当前正在执行的虚拟机字节码指令所在的地址.在虚拟机的概念模型中,字节码解释 ...

  5. 牛客国庆集训day6 B Board (模拟标记思维或找规律或分块???)

    链接:https://www.nowcoder.com/acm/contest/206/B来源:牛客网 题目描述 恬恬有一个nx n的数组.她在用这个数组玩游戏: 开始时,数组中每一个元素都是0. 恬 ...

  6. docker搭建数据库主从复制

    首先需要安装docker镜像: docker pull mysql:5.7 由于需要启动数据库才可以进入数据修改my.cnf文件,可以选择安装vi命令,也可以选择挂在 在此选择是挂载的方法进行安装: ...

  7. svn显示提交人以及时间

    eclipse使用svn显示提交人以及提交时间,方便查看自己修改过的代码,过程如下: Window-->Preferences-->Team-->SVN-->Lable dec ...

  8. 【Cracking the Code Interview(5th edition)】一、数组与字符串(C++)

    1.1 实现一个算法,确定一个字符串的所有字符是否全都不同.不允许使用额外的数据结构. 解答:这里假定字符集为ASCII码,可以与面试官沟通确认字符串使用的字符集.由于字符集是有限的,建立一个数组模拟 ...

  9. 2016 Multi-University Training Contest 10 || hdu 5860 Death Sequence(递推+单线约瑟夫问题)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5860 题目大意:给你n个人排成一列编号,每次杀第一个人第i×k+1个人一直杀到没的杀.然后 ...

  10. java登录验证码 用到spring框架

    转载:https://blog.csdn.net/zqd_java/article/details/53638143 在次大神基础上添加下述js代码即可使用了. //登陆验证 function cha ...