这篇文章主要讲simHash算法。这是一种LSH(Locality-Sensitive Hashing,局部敏感哈希)的简单实现。它是广泛用于数据去重的算法,可以用于相似网站、图片的检索。而且当两个样本差别并不大时,算法仍能起效。值得一提的是,该算法的时空复杂度不存在与维度有关的项,所以不会遭遇维度灾难,也可以在维数较高时优化kNN算法。

特征

  此算法(LSH)具有双重性,它们似乎是相悖的:

  • 对于几组不同的特征,hash相同(即冲突)的可能性要尽可能小。这也是hash基本的特征。
  • 对于几组相似的特征(即特征空间中距离小)的特征,hash相同或相似的可能性要尽可能大。这是LSH所具有的特征。

simHash实现

  simHash是LSH的其中一种对于字符串的简单实现。操作步骤如下:

  • 定义一个数代表hash,数的二进制位数可选,一般选择32bit或64bit。同时定义一个与该数位数相同的整形向量v。
  • 分割输入字符串,可以按字符数分割,也可以按空格分割。
  • 对于每个分割出来的字符串做普通hash,记hash出的值为k。约定num[i]代表num的第i位的二进制值。则对k的每位i,若k[i]>0,则v[i]+=weight,否则v[i]-=weight,weight代表该子串的权值。
  • 对于向量v的每一项,若该项大于0,则simHash的相应位置1,否则置0

  这样就可以得出一个字符串的simHash值,时间复杂度为O(|s|)。

子串相似判定

  定义两个字符串相似,即|hammingDist(simHash(str1),simHash(str2))|<=k,k是最大容忍的不同位数,hammingDist为计算两个整数海明距离的函数。海明距离即为两个整数二进制中编码不同的位数。

  根据经验,k一般取3。而海明距离的计算有一种快速的方法,给出C的实现。这种统计二进制中1的个数的算法叫平行算法,本文不再详述。

static int bitCount(unsigned int n){
    n=(n &)&0x55555555);
    n=(n &)&0x33333333);
    n=(n &)&0x0f0f0f0f);
    n=(n &)&0x00ff00ff);
    n=(n &)&0x0000ffff);
    return n;
}

int hammingDist(unsigned int a,unsigned int b){
    return bitCount(a^b);
}

查找工作

  查找新元素与已知集元素是否相似有两种方法。

  1. 时间复杂度为O(N)——线性查找算法
  2. 时间复杂度为O([C(3,32)+C(2,32)+C(1,32)]k)=O(5488k)——组合算法。

  光算出simHash值并没有太大的作用,因为判断新元素与已知集的中元素是否相似仍需较长的时间。尤其是数据量很大的时候。这时可以用一定的预处理算法优化第一种算法。

  假设k=3。优化的方法如下,将32bit或64bit(下文以32bit为例)的hash值平均分为4段。根据抽屉原理,两个字符串的hash中必有1段中没有不同的位。于是可以将每个元素hash的4个8bit作为键均预存储到表中,值为hash的完整值。查找时,只需比较新字符串hash的4个8bit表中的所有完整hash并判断海明距离是否小于等于3。这样优化后,时间复杂度降至O(4k)=O(4*n/(2^9-1))≈O(n/128),虽然仍为线性复杂度,但已经快了不少。

整体实现

  整个simHash系统的实现(C++版本)我已开源至github:https://github.com/Darksun2010/MLlearning/tree/master/LSH

MLlearning(2)——simHash算法的更多相关文章

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

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

  2. 彻底弄懂LSH之simHash算法

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

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

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

  4. xsank的快餐 » Python simhash算法解决字符串相似问题

    xsank的快餐 » Python simhash算法解决字符串相似问题 Python simhash算法解决字符串相似问题

  5. SimHash算法

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

  6. 文本去重之SimHash算法

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

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

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

  8. R语言︱文本挖掘——jiabaR包与分词向量化的simhash算法(与word2vec简单比较)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- <数据挖掘之道>摘录话语:虽然我比 ...

  9. simhash进行文本查重 Simhash算法原理和网页查重应用

    simhash进行文本查重http://blog.csdn.net/lgnlgn/article/details/6008498 Simhash算法原理和网页查重应用http://blog.jobbo ...

随机推荐

  1. Windows 2008 - 由于管理员设置的策略,该磁盘处于脱机状态

    http://blog.sina.com.cn/s/blog_59cc90640102x8m4.html 查看原文:https://www.bxl.me/9279.html准备使用云主机挂机的时候呢出 ...

  2. Emacs 配置文件

    以下是我整理的 emacs 配置文件,供刚开始玩 emacs 的同学参考.网上有人说:emacs 是神的编辑器,如果能够用到这样的编辑器,那这个人就是神了.从我个人的经验来看,emacs 是一把利器, ...

  3. 记录Qt的一个诡异Bug

    公司的一款项目,在迭代开发阶段,突然发现运行速度越来越慢,界面切换卡顿时间在2秒以上.经过和某个不卡版本的对比,惊奇的发现程序二进制都一模一样,就几个图片资源和脚本不一样.经过差不多一天的排查,发现是 ...

  4. JavaScript push()和splice()方法

    JavaScript push() 方法 定义和用法 push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度. 语法 arrayObject.push(newelement1,newele ...

  5. 安装nodejs和grunt以后出现 /usr/bin/env: node: No such file or directory

    安装完成以后需要执行此命令 sudo ln -s /usr/bin/nodejs /usr/bin/node

  6. HTTP幂等性

    http://www.cnblogs.com/weidagang2046/archive/2011/06/04/2063696.html 理解HTTP幂等性 基于HTTP协议的Web API是时下最为 ...

  7. 理解*ptr++

    这是C语言中指针的基本用法之一,我们先来看一个小例子.下面是代码: int main(void) { char *p = "Hello"; while(*p++) printf(& ...

  8. Linux 下卸载MySQL 5

    对于在Linux下通过rpm方式的mysql,我们能够通过移除这些rpm包以及删除项目的文件夹来达到卸载的目的.本文演示了在SUSE Linux 10下下载MySQL 5.5.37.详细见下文. 1. ...

  9. 《算法导论》插入排序----InsertSort

    算法导论,插入排序 public class InsertSort { public static double [] sort(double [] num) { for(int i =1; i< ...

  10. POJ-2263 Heavy Cargo---最短路变形&amp;&amp;最小边的最大值

    题目链接: https://vjudge.net/problem/POJ-2263 题目大意: 有n个城市,m条连接两个城市的道路,每条道路有自己的最大复载量.现在问从城市a到城市b,车上的最大载重能 ...