海量数据去重之SimHash算法简介和应用

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万次即可得到结果,这样以来大大提升了计算效率。

参考文章:

http://www.lanceyan.com/tech/arch/simhash_hamming_distance_similarity.html

http://taop.marchtea.com/06.03.html

http://yanyiwu.com/work/2014/01/30/simhash-shi-xian-xiang-jie.html

http://www.cnblogs.com/colorfulkoala/archive/2012/07/29/2614382.html

http://en.wikipedia.org/wiki/Locality_sensitive_hashing

http://grunt1223.iteye.com/blog/964564

时间: 2024-12-20 09:47:18

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

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

simhash算法:海量千万级的数据去重 simhash算法及原理参考: 简单易懂讲解simhash算法 hash 哈希:https://blog.csdn.net/le_le_name/article/details/51615931 simhash算法及原理简介:https://blog.csdn.net/lengye7/article/details/79789206 使用SimHash进行海量文本去重:https://www.cnblogs.com/maybe2030/p/5203186

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

搜集了快一个月的资料,虽然不完全懂,但还是先慢慢写着吧,说不定就有思路了呢. 开源的最大好处是会让作者对脏乱臭的代码有羞耻感. 当一个做推荐系统的部门开始重视[数据清理,数据标柱,效果评测,数据统计,数据分析]这些所谓的脏活累活,这样的推荐系统才会有救. 求教GitHub的使用. 简单不等于傻逼. 我为什么说累:我又是一个习惯在聊天中思考前因后果的人,所以整个大脑高负荷运转.不过这样真不好,学习学成傻逼了. 研一的最大收获是让我明白原来以前仰慕的各种国家自然基金项目,原来都是可以浑水摸鱼忽悠过去

(转)simhash算法原理及实现

simhash是google用来处理海量文本去重的算法. google出品,你懂的. simhash最牛逼的一点就是将一个文档,最后转换成一个64位的字节,暂且称之为特征字,然后判断重复只需要判断他们的特征字的距离是不是<n(根据经验这个n一般取值为3),就可以判断两个文档是否相似. 原理 simhash值的生成图解如下: 大概花三分钟看懂这个图就差不多怎么实现这个simhash算法了.特别简单.谷歌出品嘛,简单实用. 算法过程大概如下: 将Doc进行关键词抽取(其中包括分词和计算权重),抽取出

simhash算法实现--查找文件相似度

一.Simhash简介 SimHash是用来网页去重最常用的hash方法,速度很快.Google采用这种算法来解决万亿级别的网页去重任务. SimHash算法的主要思想是降维.将高维的特征向量映射成一个低维的特征向量,通过两个向量的Hamming Distance来确定文章是否重复或者高度近似. 在simhash的发明人Charikar的论文中并没有给出具体的simhash算法和证明,"量子图灵"得出的证明simhash是由随机超平面hash算法演变而来的. 参考文献:<Dete

SimHash算法

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

MLlearning(2)——simHash算法

这篇文章主要讲simHash算法.这是一种LSH(Locality-Sensitive Hashing,局部敏感哈希)的简单实现.它是广泛用于数据去重的算法,可以用于相似网站.图片的检索.而且当两个样本差别并不大时,算法仍能起效.值得一提的是,该算法的时空复杂度不存在与维度有关的项,所以不会遭遇维度灾难,也可以在维数较高时优化kNN算法. 特征 此算法(LSH)具有双重性,它们似乎是相悖的: 对于几组不同的特征,hash相同(即冲突)的可能性要尽可能小.这也是hash基本的特征. 对于几组相似的

网页内容相似度之SimHash算法

抓取的网页内容中,有大部分会是相似的,抓取时就要过滤掉,开始考虑用VSM算法,后来发现不对,要比较太多东西了,然后就发现了simHash算法,这个算法的解释我就懒得copy了,simhash算法对于短数据的支持不好,但是,我本来就是很长的数据,用上! 源码实现网上也有不少,但是貌似都是同样的,里面写得不清不楚的,虽然效果基本能达到,但是不清楚的东西,我用来做啥? 仔细研究simhash算法的说明后,把里面字符串的hash算法换成的fvn-1算法,这个在http://www.isthe.com/c

TF-IDF算法简介

TF-IDF算法全称为term frequency–inverse document frequency.TF就是term frequency的缩写,意为词频.IDF则是inverse document frequency的缩写,意为逆文档频率. 该算法在信息处理中通常用来抽取关键词.比如,对一个文章提取关键词作为搜索词,就可以采用TF-IDF算法. 要找出一篇文章中的关键词,通常的思路就是,就是找到出现次数最多的词.如果某个词很重要,它应该在这篇文章中多次出现.于是,我们进行"词频"

最小生成树 kruskal算法简介

生成树--在一个图中的一个联通子图  使得所有的节点都被(访问) 最小生成树 (MST) 即联通子图的总代价(路程)最小 已知的一个图 有n个点 m条边 kruskal的算法如下 先对边从小到大排序 从最小的边起,不停的合并这条边的两个节点到一个集合,如果这条边的两个节点已经在一个集合里,则无视,否则形成回路(显然错误)直到所有的节点并到一个集合里 这里需要用到并查集来合并节点 1 int cmp(const int i,const int j) { 2 return w[i] < w[j];