SimHash

有这么一个场景: 我们想衡量两个item之间的相似度(即距离, 比如计算两篇doc的相似度来进行去重). 每个item都用一个feature vector来表示. 这个vector往往很稀疏, vector的每个维度的值常表示某特征是否存在{0, 1}或出现的次数或者重要性.

一个传统的还不错的方法是使用杰卡德相似度(Jaccard Similarity). JS能很好地衡量两个集合(稀疏vector)的相似度, 公式即 distance()=sizeof()sizeof() . 然而Jaccard Similarity的缺点在于, 复杂度高(求交, 求并), 并且若想找到与某item相似的”同类items”(比如疑似重复的doc), 就得计算该item与所有其它item的距离. 一句话, 质量有余效率不足.

这时候就有人提出, 我们能不能给每个item都算一个指纹hash, 用指纹hash来表征这个item. 如果两个item的指纹的距离, 可以迅速收敛到两个item本身的距离, 那就太好了. 在此诉求下, 局部敏感性哈希(Locality-sensitive Hashing, LSH)应运而生了. 简单来说, LSH就是这么一种哈希映射: 两个item的距离, 在映射前后是等价的. 有了LSH, 我们就可以给每个item都算一个LSH指纹, 用简单的指纹间距离来替代复杂Jaccard距离. simhash就是一种有名的LSH.

SimHash的计算步骤

SimHash

  • 对于一个item, 它有一个稀疏的feature vector. 比如是一篇文章, 由n个词组成. 对于每一个feature(词), 都用普通hash(md5, sha等)计算出一个hash. 这样一个item就得到了n个hash. 如果想要的bit数少于md5, 可以取md5(词)的前k bit.
  • 将这n个hash归并成一个hash: 将这n个hash 按位加起来. 加的时候注意, 一是加权相加, 每个hash的每个bit, 都乘以这个特征的weight(比如词出现的频数); 二是遇到1就加weight, 遇到0就减weight, (即0被视为-1, 如图).
  • 然后, 每位上计数若 0则取1, <0则取0. 如此将n个特征的共n片hash 按位归并成一个. 结果hash的bit数和用的md5的bit数是一样的.

应用与索引

一个典型的应用实例是Google论文中提到的: 搜索引擎的爬虫在爬取doc时, 希望知道当前这个doc是否已经在doc库中(主体内容一样). 此时可以计算当前doc的simhash, 再跟库中各doc的simhash值比对, 看是否有相似的(hamming distance <= threshold). 若库中已有相似hash值的doc, 可认为主体内容一致. 论文中使用的参数: length(hash)=64 bit, threshold(distance)=3.
如何根据simhash快速判断是否有一样doc? 虽然计算doc距离的效率提高了, 若想判断当前doc是否已存在, 我们仍要进行O(n=#doc)的比对, 这不够快. 所以需要给库中的doc建一个索引, 以便快速查找. Google在把simhash用来做去重的时候,海明距离小于等于3的即为相似的网页。simhash为64位,那么根据抽屉原理,把hash平均分为4份的话,至少有一份是完全相同的。那么对于一个网页,你就可以建4个KV结构的map或索引,平均分成4份,每一份作为一个key。具体实现细节见论文或这篇博客.


参考资料:
Google paper: Detecting Near-Duplicates for Web Crawling
Simhashing (hopefully) made simple
Similarity Estimation Techniques from Rounding Algorithms
Wikipedia: Locality-sensitive Hashing
Simhash的巧妙
我的数学之美系列二 —— simhash与重复信息识别

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值