第一种是方案是查找待查询文本的64位simhash code的全部3位之内变化的组合,大约须要四万屡次的查询,参考下图:html
第二种方案是预生成库中全部样本simhash code的3位变化之内的组合,大约须要占据4万多倍的原始空间,参考下图 git
上述两种方法,或者时间复杂度,或者空间复杂度,其一没法知足实际的需求。咱们须要一种方法,其时间复杂度优于前者,空间复杂度优于后者。 假设咱们要寻找海明距离3之内的数值,根据抽屉原理,只要咱们将整个64位的二进制串划分为4块,不管如何,匹配的两个simhash code之间至少有一块区域是彻底相同的,如图所示 github
因为咱们没法事先得知彻底相同的是哪一块区域,所以咱们必须采用存储多份table的方式。在本例的状况下,咱们须要存储4份table,并将64位的simhash code等分红4份;对于每个输入的code,咱们经过精确匹配的方式,查找前16位相同的记录做为候选记录,如图所示:算法
让咱们来总结一下上述算法的实质:数组
一、将64位的二进制串等分红四块函数
二、调整上述64位二进制,将任意一块做为前16位,总共有四种组合,生成四份table post
三、采用精确匹配的方式查找前16位 性能
四、若是样本库中存有2^34(差很少10亿)的哈希指纹,则每一个table返回2^(34-16)=262144个候选结果,大大减小了海明距离的计算成本测试
咱们能够将这种方法拓展成多种配置,不过,请记住,table的数量与每一个table返回的结果呈此消彼长的关系,也就是说,时间效率与空间效率不可兼得! 这就是Google天天所作的,用来识别获取的网页是否与它庞大的、数以十亿计的网页库是否重复。另外,simhash还能够用于信息聚类、文件压缩等。url
SimHash 算法原理
simhash用于比较大文本,好比500字以上效果都还蛮好,距离小于3的基本都是类似,误判率也比较低。可是若是咱们处理的是微博信息,最多也就140个字,使用simhash的效果并不那么理想。看以下图,在距离为3时是一个比较折中的点,在距离为10时效果已经不好了,不过咱们测试短文本不少看起来类似的距离确实为10。若是使用距离为3,短文本大量重复信息不会被过滤,若是使用距离为10,长文本的错误率也很是高,如何解决?——采用分段函数!
SimHash 算法原理——评估结果
一、dump 一天的新闻数据:
数据项要求:标题、内容、新闻原始地址。
二、评估指标
排重准确率(97%): 数据集:排从新闻集
方式:人工(研发先评估、产品评估)
召回率(75%):
数据集:训练数据集-排从新闻集
方式:扩大海明距离,再进行人工评估
SimHash 算法原理——代码片断
高效计算二进制序列中1的个数:这个函数来计算的话,时间复杂度是 O(n); 这里的n默认取值为3。因而可知仍是蛮高效的。