转 文本相似性算法Simhash原理及实践

本文详细介绍了Simhash算法的背景、原理和计算过程,包括其与局部敏感性哈希的关系。Simhash通过将文本转换为哈希签名,能有效计算文本相似度,常用于大数据量的相似文本查找。文章还探讨了Simhash的优缺点及其在重复信息识别中的应用场景,提供了具体的代码示例和参考资料。
摘要由CSDN通过智能技术生成

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow

也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!

               




simhash(局部敏感哈希)的原理


simhash的背景 
simhash广泛的用于搜索领域中,也许在面试时你会经常遇到这样的问题,如果对抓取的网页进行排重,如何对搜索结果进行排重等等。随着信息膨胀时代的来临,算法也在不断的精进,相似算法同样在不断的发展,接触过lucene的同学想必都会了解相似夹角的概念,那就是一种相似算法,通过计算两个向量的余弦值来判断两个向量的相似性,但这种方式需要两两进行计算向量的余弦夹角,计算量比较大,不能用于实时计算或是大数据量的运算,比如在做搜索结果的相似性排重时,需要对上千条结果进行相似性排重,如果两两比对的话,最少也需要进行上千次的向量余弦值计算,其中涉及到分词,特征提取,余弦值计算等,很难满足性能的需要。

jaccard相似度也是一种相似算法,它的计算方式比较直观,就是sim(x,y)= (x∩y) / (x∪y),例如:
     若 S={a, d}T={a, c, d} 
     则 Jaccard_Sim(S, T) = |{a, d}|/|{a, c, d}| = 2/3

也是一种需要实时生成特征向量并且进行计算的算法。

那么

什么是simhash呢?

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 作为签名。

对两篇文档,它们的 Simhash 值之间不同位的个数越少(即海明距离越小),它们之间的 Jaccard 相似度越高。

什么是局部敏感性哈希呢?
局部敏感哈希(LSH)是指这样的哈希方法:对两篇文档,如果它们相似,则它们的哈希值有较高的概率是相同的。有了文档的最小哈希签名,我们就能实现这种哈希方法。直观的做法是,将包含 b×r 个值最小哈希签名分为 b 等份,每份 r 个,对两个文档,定义 P 为两个文档至少含有1个相同份的概率,显然,文档间的Jaccard 相似度越高,哈希签名具有相同值的位数就越多,概率 P 就越大。
如何计算simhash呢?
simhash从内部看就是特征向量hash叠加的效果,并且具有局部敏感性,普通的hash算法针对差别不大的字符串会产生截然不同的hash值,但是simhash计算出来的hash值的海明距离会很相近。
具体的算法是将doc分解为特征向量,具体可以通过分词,也可以通过bigram实现,并且可以赋予一定的权重,针对每个向量使用统一的hash函数进行hash,针对每个特征的hash值的每一位,如果是1就对simhash值的对应位加1,当然也可以使用权重,如果对应位是0,则simhash的对应位减1,对最后的simhash值如果该位大于0则该位置1,如果该位小于0,则该位置0,最后就可以得到一个真正的simhash值。
过程可以参考下面:
simhash过程

汉明距离的计算代码如下:
[cpp]  view plain   copy
  1. /************************************************************************* 
  2.         > File Name: hamdistance.c 
  3.         > Author: desionwang 
  4.         > Mail: wdxin1322@qq.com  
  5.         > Created Time: Wed 20 Nov 2013 02:02:13 PM CST 
  6.  ************************************************************************/  
  7.   
  8. #include<stdio.h>  
  9. #include<stdint.h>  
  10. int hamdistance(uint64_t sim1, uint64_t sim2){  
  11.         uint64_t xor_val = sim1 ^ sim2;  
  12.         int distance = 0;  
  13.         while(xor_val > 0){  
  14.                 xor_val = xor_val & (xor_val - 1);  
  15.                 distance++;  
  16.         }  
  17.         return distance;  
  18. }  
  19.   
  20. int main(int argc, char *argv[]){  
  21.         uint64_t sim1 = 851459198;  
  22.         uint64_t sim2 = 847263864;  
  23.         int dis = hamdistance(sim1, sim2);  
  24.         printf("hamdistance of %lu and %lu is %d", sim1, sim2, dis);  
  25. }  

输出为:
hamdistance of 851459198 and 847263864 is 4
simhash的好处?
simhash离线计算指纹,方便了大规模数据比较时的消耗,不需要在计算时提取特征进行计算,hash值的可比性很强,只需要比较汉明距离,
方便了从海量数据中发掘相似项的实现,试想一个新文档同百万级甚至千万级数据做相似夹角的情况。simhash大大减少了相似项排重的复杂度。
如何应用simhash呢,具体的应用场景?
simhash有两个比较典型的应用,一个是网页抓取的排重,一个是检索时相似doc 的排重
前者是在大集合中寻找是否具有相似项,后者是对检索的集合进行滤重。

检索集中发现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值