这篇文章想给大家介绍一个神奇的东东:LSH首先看看它有什么用先~它可以快速地找出海量数据中的相似数据点,听着有点抽象?那我们来举个实际的例子,比如说你有海量的网页(这里的网页是指你拥有的本地数据,不是指互联网上的),你现在想找和一个特定网页相似的其它网页,就比如你想在海量的网页中找出和我这篇博文相似的网页~最naive的方法就是去遍历整个数据集,一个一个页面去比较,看看哪一个页面和我的这个页面最相似,当然所谓的相似需要你自己去定义,可以用Cosine Similarity、Jaccard Coefficient等去衡量(可以参考我的另一篇博文:常用相似性、相关性度量指标),至于特征向量的构造,那就有很多方法了,如使用分词后的各词的TF-IDF值,这里就不展开了。

现在假设你已经对各个页面提取好了特征,那下面的事情就是:给定一个特征,如何快速地从海量的特征中找到和这个特征相似的一些特征?这时候LSH就闪亮登场了(鼓掌ing...),先看看它的名字,Locality Sensitive Hashing,局部敏感哈希。哈希大家应该都知道,它的查找时间复杂度是O(1),有着极高的查找性能,那什么叫“局部敏感”的哈希?它的意思就是:如果原来的数据相似,那么hash以后的数据也保持一定的相似性,这玩意就叫局部敏感哈希。

来看看我们通常的哈希,比如有一个hash function: f(x)=(x*7)%10,有两个数据x1=123,x2=124,现在用f(x)把它们hash一下,f(x1)=1,f(x2)=8,这想说明什么呢?看看原来的数据,是不是很相似?(假设用欧氏距离度量)再看hash后的数据,那就差得远了,说明这个hash它并没有保持相似性,那么这种就不是局部敏感哈希。

那么LSH就是一种在hash之后能保持一定的相似性神奇玩意儿,这里为什么说是“保持一定的相似性”?因为我们知道,hash函数的值域一般都是有限的,但是要哈希的数据却是无法预知的,可能数据大大超过其值域,那么就不可能避免地会出现一个以上的数据点拥有相同的hash值,这有什么影响呢?假设有一个很好的hash function,好到可以在hash之后很好地保持原始数据的相似性,假设它的不同取值数是10个,然后现在我有11个截然不相似的数据点,想用这个hash function来hash一下,因为这个hash function的不同取值数是10个,所以必然会出现一个hash桶中有1个以上的数据点,那刚才不是说11个截然不相似的数据点吗?它们应该有不同的hash值才对啊。没错,的确希望它是这样,但实际上很难,只能在hash之后保持一定的相似性。其根本原因就是在做相似性度量的时候,hash function通常是把高维数据映射到低维空间上,为什么映射到低维空间上?因为高维空间上计算复杂度太高。

降维会对相似性度量造成什么影响?数据的维数在某种程度上能反映其信息量,一般来说维数越多,其反映的信息量就越大,比如说对于一个人,假设有一个一维数据:(姓名),有一个三维数据(姓名,身高,体重),那么这个三维数据反映的信息是不是要比一维的多?如果我们知道的信息越多,是不是就能越准确地判定两个东西的相似性?所以,降维就在某种程度上造成的信息的丢失,在降维后的低维空间中就很难100%保持原始数据空间中的相似性,所以刚才是说“保持一定的相似性”。

好家伙,一方面想把数据降维,一方面又希望降维后不丢失信息,这是不可能的,那么就要做一个妥协了,双方都让一步,那么就可以实现在损失一点相似性度量准确性的基础上,把数据降维,通常来说,这是值得的。说了这么多,那LSH究竟是如何做的呢?先一句话总结一下它的思想吧:它是用hash的方法把数据从原空间哈希到一个新的空间中,使得在原始空间的相似的数据,在新的空间中也相似的概率很大,而在原始空间的不相似的数据,在新的空间中相似的概率很小。

其实在用LSH前通常会进行一些降维操作,我们先看看下面这张图:

先说说整个流程,一般的步骤是先把数据点(可以是原始数据,或者提取到的特征向量)组成矩阵,然后通过第一步的hash functions(有多个哈希函数,是从某个哈希函数族中选出来的)哈希成一个叫“签名矩阵(Signature Matrix)”的东西,这个矩阵可以直接理解为是降维后的数据,然后再通过LSH把Signature Matrix哈希一下,就得到了每个数据点最终被hash到了哪个bucket里,如果新来一个数据点,假如是一个网页的特征向量,我想找和这个网页相似的网页,那么把这个网页对应的特征向量hash一下,看看它到哪个桶里了,于是bucket里的网页就是和它相似的一些候选网页,这样就大大减少了要比对的网页数,极大的提高了效率。注意上句为什么说是“候选网页”,也就是说,在那个bucket里,也有可能存在和被hash到这个bucket的那个网页不相似的网页,原因请回忆前面讲的“降维”问题。。但LSH的巧妙之处在于可以控制这种情况发生的概率,这一点实在是太牛了,下面会介绍。

由于采用不同的相似性度量时,第一步所用的hash functions是不一样的,并没有通用的hash functions,因此下面主要介绍两种情况:(1)用Jaccard相似性度量时,(2)用Cosine相似性度量时。在第一步之后得到了Signature Matrix后,第二步就都一样了。

先来看看用Jaccard相似性度量时第一步的hash functions。

假设现在有4个网页(看成是document),页面中词项的出现情况用以下矩阵来表示,1表示对应词项出现,0则表示不出现,这里并不用去count出现了几次,因为是用Jaccard去度量的嘛,原因就不用解释了吧。

好,接下来我们就要去找一种hash function,使得在hash后尽量还能保持这些documents之间的Jaccard相似度

目标就是找到这样一种哈希函数h(),如果原来documents的Jaccard相似度高,那么它们的hash值相同的概率高,如果原来documents的Jaccard相似度低,那么它们的hash值不相同的概率高。这玩意叫Min-Hashing。
         
        Min-Hashing是怎么做的呢?请看下图:

首先生成一堆随机置换,把Signature Matrix的每一行进行置换,然后hash function就定义为把一个列C hash成一个这样的值:就是在置换后的列C上,第一个值为1的行的行号。呼,听上去好抽象,下面看列子:

图中展示了三个置换,就是彩色的那三个,我现在解释其中的一个,另外两个同理。比如现在看蓝色的那个置换,置换后的Signature Matrix为:

然后看第一列的第一个是1的行是第几行,是第2行,同理再看二三四列,分别是1,2,1,因此这四列(四个document)在这个置换下,被哈希成了2,1,2,1,就是右图中的蓝色部分,也就相当于每个document现在是1维。再通过另外两个置换然后再hash,又得到右边的另外两行,于是最终结果是每个document从7维降到了3维。我们来看看降维后的相似度情况,就是右下角那个表,给出了降维后的document两两之间的相似性。可以看出,还是挺准确的,回想一下刚刚说的:希望原来documents的Jaccard相似度高,那么它们的hash值相同的概率高,如果原来documents的Jaccard相似度低,那么它们的hash值不相同的概率高,如何进行概率上的保证?Min-Hashing有个惊人的性质:

就是说,对于两个document,在Min-Hashing方法中,它们hash值相等的概率等于它们降维前的Jaccard相似度。下面来看看这个性质的Proof:
         设有一个词项x(就是Signature Matrix中的行),它满足下式:

就是说,词项x被置换之后的位置,和C1,C2两列并起来(就是把两列对应位置的值求或)的结果的置换中第一个是1的行的位置相同。那么有下面的式子成立:

就是说x这个词项要么出现在C1中(就是说C1中对应行的值为1),要么出现在C2中,或者都出现。这个应该很好理解,因为那个1肯定是从C1,C2中来的。

那么词项x同时出现在C1,C2中(就是C1,C2中词项x对应的行处的值是1)的概率,就等于x属于C1与C2的交集的概率,这也很好理解,属于它们的交集,就是同时出现了嘛。那么现在问题是:已知x属于C1与C2的并集,那么x属于C1与C2的交集的概率是多少?其实也很好算,就是看看它的交集有多大,并集有多大,那么x属于并集的概率就是交集的大小比上并集的大小,而交集的大小比上并集的大小,不就是Jaccard相似度吗?于是有下式:

又因为当初我们的hash function就是

往上面一代,不就是下式了吗?

这就证完了,这标志着我们找到了第一步中所需要的hash function,再注意一下,现在这个hash function只适用于Jaccard相似度,并没有一个万能的hash function。有了hash functions,就可以求Signature Matrix了,求得Signature Matrix之后,就要进行LSH了。
         首先将Signature Matrix分成一些bands,每个bands包含一些rows,如下图所示:

然后把每个band哈希到一些bucket中,如下图所示:

注意bucket的数量要足够多,使得两个不一样的bands被哈希到不同的bucket中,这样一来就有:如果两个document的bands中,至少有一个share了同一个bucket,那这两个document就是candidate pair,也就是很有可能是相似的。
       下面来看看一个例子,来算一下概率,假设有两个document,它们的相似性是80%,它们对应的Signature Matrix矩阵的列分别为C1,C2,又假设把Signature Matrix分成20个bands,每个bands有5行,那么C1中的一个band与C2中的一个band完全一样的概率就是0.8^5=0.328,那么C1与C2在20个bands上都没有相同的band的概率是(1-0.328)^20=0.00035,这个0.00035概率表示什么?它表示,如果这两个document是80%相似的话,LSH中判定它们不相似的概率是0.00035,多么小的概率啊!
       再看先一个例子,假设有两个document,它们的相似性是30%,它们对应的Signature Matrix矩阵的列分别为C1,C2,Signature Matrix还是分成20个bands,每个bands有5行,那么C1中的一个band与C2中的一个band完全一样的概率就是0.3^5=0.00243,那么C1与C2在20个bands至少C1的一个band和C2的一个band一样的概率是1-(1-0.00243)……20=0.0474,换句话说就是,如果这两个document是30%相似的话,LSH中判定它们相似的概率是0.0474,也就是几乎不会认为它们相似,多么神奇。
       更为神奇的是,这些概率是可以通过选取不同的band数量以及每个band中的row的数量来控制的:

除此之外,还可以通过AND和OR操作来控制,就不展开了。
        
        呼,LSH的核心内容算是介绍完了,下面再简单补充一下当相似性度量是Cosine相似性的时候,第一步的hash function是什么。它是用了一个叫随机超平面(Random Hyperplanes)的东西,就是说随机生成一些超平面,哈希方法是看一个特征向量对应的点,它是在平台的哪一侧:

这个可以直观地想象一下,假设有两个相交的超平面,把空间分成了4个区域,如果两个特征向量所对应的点在同一域中,那么这两个向量是不是挨得比较近?因此夹角就小,Cosine相似度就高。对比一下前面用Jaccard相似度时Signature Matrix的生成方法,那里是用了三个转换,在这里对应就是用三个随机超平面,生成方法是:对于一个列C(这里因为是用Cosine相似度,所以列的值就不一定只是0,1了,可以是其它值,一个列就对应一个特征向量),算出该列对应的特征向量的那个点,它是在超平面的哪个侧,从而对于每个超平面,就得到+1或者-1,对于三个超平面,就得到三个值,就相当于把原来7维的数据降到三维,和前面用Jaccard相似度时的情况是不是很像?得到Signature Matrix后,就进行LSH,步骤是一样的~~~~~~~

参考:Stanford CS246课程PPT关于Locality Sensitive Hashing的章节,http://cs246.stanford.edu
--------------------- 
作者:Kenney_Qin 
来源:CSDN 
原文:https://blog.csdn.net/OrthocenterChocolate/article/details/38943491 
版权声明:本文为博主原创文章,转载请附上博文链接!

Locality Sensitive Hashing ( LSH,局部敏感哈希 ) 详解相关推荐

  1. KD树和LSH局部敏感哈希

    文档结构 文档表示 距离度量 KD树 原理 构建 查询 复杂度 KD树的KNN KD树的逼近KNN 不适用高维数据 LSH LSH潜在的问题 LSH算法 复杂度 概率逼近 多表 文档结构 文档表示 词 ...

  2. LSH(局部敏感哈希算法)实现文本的相似性比对

    源码见github:https://github.com/smallsmallcase/lsHash 和LSH算法类似,朴素贝叶斯算法也能实现相近的分类功能,朴素贝叶斯算法给新浪新闻分类的代码见:ht ...

  3. minHash(最小哈希)和LSH(局部敏感哈希)

    在数据挖掘中,有一个比较基本的问题,就是比较两个集合的相似度.关于这个问题,最笨的方法就是用一个两重循环来遍历这两个集合中的所有元素,进而统计这两个集合中相同元素的个数.但是,当这两个集合里的元素数量 ...

  4. R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(一,基本原理)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 私认为,文本的相似性可以分为两类:一类是机械相 ...

  5. 最近邻和K近邻及其优化算法LSH(局部敏感哈希,Locality Sensitive Hashing) Kd-Tree

    引言 在处理大量高维数据时,如何快速地找到最相似的数据是一个比较难的问题.如果是低维的小量数据,线性查找(Linear Search)就可以解决,但面对海量的高维数据集如果采用线性查找将会非常耗时.因 ...

  6. Locality Sensitive Hashing(局部敏感哈希)

    文章目录 Background运用背景 Big pitcture 整体架构 定义 Surprising Property References # 写在前面的话 酱酱,又到了程序媛拯救世界的时间,程序 ...

  7. 推荐系统局部敏感哈希解决Embedding最近邻搜索问题

    文章目录 快速Embedding最近邻搜索问题 聚类.索引搜索最近邻 聚类搜索最近邻 索引搜索最近邻 局部敏感哈希及多桶策略 局部敏感哈希的基本原理 局部敏感哈希的多桶策略 局部敏感哈希代码实现 快速 ...

  8. 局部敏感哈希(Locality Sensitive Hashing)二三问[2]

    #写在前面的话 今天的这一章有几个目的,一是回答一下各位网友在各大博客上提出的问题,然后其他博主没有回答的问题.二是纠正一些别人在写局部敏感哈希时候出现的错误.就是这么贴心有没有. #假装自己是正文的 ...

  9. 局部敏感哈希算法(Locality Sensitive Hashing)

    from:https://www.cnblogs.com/maybe2030/p/4953039.html 阅读目录 1. 基本思想 2. 局部敏感哈希LSH 3. 文档相似度计算 局部敏感哈希(Lo ...

  10. 局部敏感哈希-Locality Sensitive Hashing

    局部敏感哈希 转载请注明http://blog.csdn.net/stdcoutzyx/article/details/44456679  在检索技术中,索引一直需要研究的核心技术.当下,索引技术主要 ...

最新文章

  1. LeetCode hard 84. Largest Rectangle in Histogram--python,java 15行,c++ 15行 解法
  2. 使用 python 的单人AI 扫雷游戏
  3. RHTTPHeaders有bug,使用须谨慎
  4. Interface Builder nib2objc ibtool
  5. VisualSVN server 无法启动
  6. Android热修复技术原理详解(最新最全版本)
  7. mysql 备份工具xtrabackup全备与还原图解
  8. 【Matplotlib】【Python】如何使用matplotlib绘制绘制随机生成的点--随机漫步详解
  9. 两台服务器之间mysql数据库怎么做同步_MySQL 数据库同步结构总结
  10. index.php后有乱码后缀,phpExcel在线下wamp环境下,正常导出,同样的代码到线上Linux导出文件无法打开,修改文件后缀为.xls后乱码...
  11. Oracle expdp和impdp
  12. Impala的操作命令之 内外shell
  13. java 3d文字旋转_3d多物体点旋转
  14. etl spring_山寨一个Spring的@Component注解
  15. 机器学习开篇之机器学习的分类
  16. python二维数组第一列_Python遍历numpy数组的实例 python中如何提取一组数据中的第一列数据...
  17. 手机开热点如何查看接入热点的所有ip
  18. C++ iterator(迭代器)用法
  19. python基础学习与应用
  20. 【OCM】Oracle 10g OCA-OCP-OCM 证书体系展示,纪念2012

热门文章

  1. 入门编程(小白写代码的神器)
  2. 绝顶高手是这样快速画美女的!
  3. 数据分析的 5 种细分方法
  4. wireshark使用说明
  5. python定义变量取值范围_python怎么限定函数自变量取值范围?
  6. 基于微信小程序的毕业设计题目(31)共享会议室预约小程序(含开题报告、任务书、中期报告、答辩PPT、论文模板)
  7. 在注册表里查找classid
  8. 机器学习实战 | SKLearn入门与简单应用案例
  9. 10月10日第壹简报,星期一,农历九月十五
  10. 如何选择适合你的兴趣爱好(六),钢琴