高效相似度计算 LSH minHash simHash的学习

版权声明: 本文为博主原创文章,未经博主允许不得转载 https://blog.csdn.net/u011467621/article/details/49685107

joey 周琦

本文首先介绍了局部敏感哈希的概念与用处,然后介绍了常见的快速计算相似度、寻找近邻的方法minHash, simHash

局部敏感哈希Locality-sensitive hashing (LSH)

定义

首先我们看看wiki上比较准确的英文描述[1]。
An LSH family F is defined for a metric space M=(M,d) , a threshold R>0 and an approximation factor c>1. This family F is a family of functions h:MS which map elements from the metric space to a bucket sS . The LSH family satisfies the following conditions for any two points p,qM , using a function hF which is chosen uniformly at random:

  • if d(p,q) R, then h(p)=h(q) (i.e.,p and q collide) with probability at least P1 ,
  • if d(p,q) cR, then h(p)=h(q) with probability at most P2 .
    A family is interesting when P1>P2 . Such a family F is called (R,cR,P1,P2) -sensitive.

wiki关于metric space给出的定义

In mathematics, a metric space is a set for which distances between all members of the set are defined. Those distances, taken together, are called a metric on the set.

根据上述信息,我中文理解下。 局部敏感哈希(Locality-sensitive hashing)是为了度量空间 M=(M,d) (metric space)定义的函数族,将度量空间的不同元素映射到相应的桶(bucket)中。满足以下性质:

  • if d(p,q) R, then h(p)=h(q) (i.e.,p and q collide) with probability at least P1 ,
  • if d(p,q) cR, then h(p)=h(q) with probability at most P2 .
    A family is interesting when P1>P2 . Such a family F is called (R,cR,P1,P2) -sensitive.

其中 R 是一个阈值, c 是一个近似因子。 d 则是度量空间的一种距离的计算方式,常见的有余弦距离,Jaccard距离,编辑距离等。上述两个性质可以从下图看的更明显。这里写图片描述

横坐标表示距离,纵坐标可以理解两个点(下面用“点”来统一代替文档,item,或物品等名称,在应用都可以视为一种东西)被放入一个桶(即认为二者较为相似)的概率。可以看出LSH可以将距离较近的点以至少概率 p1 的概率归为类似,距离远的点至多有概率 p2 归为类似

意义Motivation

一个算法或概念的意义是很重要的。我们学习这个概念算法到底可以解决什么问题?适用于哪些场景?
刚才看了LSH的定义,那么这个东西有啥用,哪些场景可以用呢?如何在海量数据中找到一个高维度点相似的点集合?(搜索中找出最相关的query, 视频业务中找到最接近重复的视频,等等)最简单的方法是计算每个点与该点的距离,然后排序。然后如果面对海量数据,这种暴力计算的方法是不可取的。如果我们可以找到一类函数LSH,高效率的将任意两个点是否很接近找出来,就可以解决上述问题。常见的LSH方案有minHash,simHash. 下面分别简单介绍下

minHash

相关概念

  • Jaccard similarity coefficient (Jaccard系数) 是常见的衡量两个集合相似度的度量:
    J(A,B)=|AB||AB|
  • 利用矩阵代表集合,例:有四个集合 S1={a,d} , S2={c} , S3={b,d,e} , S4={a,c,d} ,可用下图的矩阵表示[参考2]
    这里写图片描述

minHashing

minHash ( min-wise independent permutation LSH scheme) 可以快速估计两个集合的相似度。为了minHash一个集合,首先将该集合用矩阵表示,然后随机选取行索引的一个排列(permutation), 该集合的minHash的值是按照这个排列遇见的第一个为1的行的索引。
下面看例子,将上述矩阵的行按照一个随机的排列如下,那么minHash( S1 )=a, minHash( S2 )=c, minHash( S3 )=b, minHash( S4 )=a
这里写图片描述

性质

对于一个随机的排列,两个集合的minHash相等的概率等于两个集合的Jaccard相似度

Pr[minHash(A)=minHash(B)]=J(A,B)

证明参考[2]第三章,例子也来自于此书。

假设 {S1,...SM} M个集合共有 N 个元素,即那个矩阵有 N 行, minHash的思想是随机选取 n 个排列(permutation) , n<<N , 那么我们可以用minHash得到的 n 维度向量 [h1(S),...,hn(S)]T 来代替集合 S ,可以看出原来 N 维度的向量被压缩为了 n 维度。

在现实中排列一个很大的行索引也是很慢的,所以一般用随机的哈希函数来替代排列.

还是依据上面的矩阵表示,我们这里用两个哈希函数(x+1 mod 5 和3x+1 mod 5)代表两个排列.
这里写图片描述

对于第一个排列(x+1 mod 5)的含义,新第0行对应的第4行,新的第一行为原来的第0行,所以第一个排列的顺序为[4 0 1 2 3 4], 第二个排列为[3 0 2 4 1]. 那么根据minHash的定义,我们可以得到
这里写图片描述

当然这是我们根据肉眼看的,那么如何通过一个算法得到呢?
若S 表示集合的矩阵表示。初始化新的minHash矩阵K, 每列代表一个集合,每行代表一个排列,矩阵每个元素初始化为 . 下面 N 代表原来的feature个数, n 代表新的排列个数, M 代表集合个数。在实例中 N=5,n=2,M=4

1 根据哈希算出每行的 h1(i),...,hn(i).(i=1...N)
2 For i = 1:N
For c = 1:M
如果S[i,c]为0;跳过
否则;对于每个排列r=1…n, K(r,c) = min ( K(r,c), h_r(i) )
上述例子的更新过程如下面几幅图这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

通过上面的过程,每个集合就可以用一个 n 维向量来表示,已经大大压缩了数据,然而面对海量数据,若要找出任意两个点的相似度,依然是一个很大的计算量。然后在很多应用中,我们之需要找出与某点相似的点的集合即可,而不用算出每个pair对的相似度。

书[2]中描述了一种桶方式,可以高效率的找出相似的pair对。上面得到向量可以分为 b 段(桶),每个段有 r 个行,假设两个点的Jaccard相似度为 s ,根据“minHash的值相等的概率等于Jaccard相似度”这个定理,若两个点在某个段完全相同,则认为这两个点为相似对。分析如下

  • 两个点在一个段中,完全一样的概率为 sr
  • 两个点在一个段中,不完全一样的概率为 1sr
  • 两个点在所有段中,不完全一样的概率为 (1sr)b
  • 两个点至少有一个段相同的概率为, 1(1sr)b

最后一行的这个函数可以画成一个S曲线,横轴为Jaccard相似度,纵轴为被选择为相似对的概率
这里写图片描述

根据上述技术(Banding Technique), 就可以高效率的找出任意点的相似点有哪些。

上面我们看到了如何利用minHash和banding technique来对一个集合表示进行降维和快速找出近邻。

simHash

从上面可以minHash方法比较适合集合表示或者说(0,1)数据类型的降维与近邻查找。若某个点(如最开始说的,可以为item,object,物品,文档等等)在每个特征上面有相应的权重,如果想要利用上权重的信息那么minHash的方法就不适用了。可以使用simHash。

论文[4]提出simHash,论文[5]将simHash运用到了网页的去重应用中,并且给出了快速查找近邻的方法。下面我只简单介绍下simHash的实习方法,原理部分自己也没太搞懂。

输入:有很多点(doc or item or..),每个点可以用一串(feature,weight)((特征,权重))表示。
输出: 每个点用一个固定长度f的(如64)的二进制数表示

求解过程:

  • 对于每个点p将其每个feature通过一个哈希函数(如MD5)哈希为二进制长度为f的值。如 [(hash[feature1],weight1),...,(hash[featureN],weightN)] ,每个点的特征数目可以不同。
  • 若用浮点数组p_float(64位)来代表点p,具体方式如下, 对于每一位 i=1...64
    • v_float[i]=j=1N indicator(hash[featurej][i])weightj
    • 其中 hash[featurej][i] 代表第j个特征的第i个bit位
    • indicator是一个指示函数,indicator(f) = 1 if f>0 else -1
  • 得到了浮点数组p_float, 那么数组的每一位若为正则点p的二进制表示的那位上为1,否则为0.
  • 通过上述方式我们就讲任意点映射(压缩)到了一个固定长度的二进制数上了。利用这个结果可以进行快速查重,找近邻,聚类等功能

结论

一般情况若每个feature无权重,则minHash效果优于simHash[3], 有权重时simHash合适(因为minHash没办法用)

参考文献

  1. https://en.wikipedia.org/wiki/Locality-sensitive_hashing
  2. Mining of Massive Datasets
  3. In Defense of MinHash Over SimHash
  4. Similarity Estimation Techniques from Rounding Algorithms
  5. Detecting Near-Duplicates for Web Crawling: similiarty research

猜你喜欢

转载自blog.csdn.net/u011467621/article/details/49685107
LSH
今日推荐