欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

Locality Sensitive Hashing

发布时间:2024/4/18 编程问答 40 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Locality Sensitive Hashing 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

https://sanzo.top/Algorithm/Locality-Sensitive-Hashing

试想你有一些文本它们可能有所重复,你需要对他们进行去重处理,传统的做法是O(N2)O(N^2)O(N2),即对所有的文本对进行相似度的计算,然后进行排序得到结果。

假设N=106N=10^6N=106,需要进行N(N−1)2=5×1011\frac{N(N-1)}{2} = 5\times10^{11}2N(N1)=5×1011次计算,在果每秒计算10610^6106次,一天大概10510^5105秒,那么需要5天的时间,如果N=107N = 10^7N=107,则需要超过一年的时间。

显然O(N2)O(N^2)O(N2)的复杂度不可取,Locality-Sensitive-Hashing(LSH)利用hash把相似高的文本分到同一个桶中,这样过滤了大量不同的本文将计算降低到O(N)O(N)O(N)

对于具体的任务,一般分为一下三个步骤:

  • Shingling,将文本转化为集合。
  • Min-Hashing,在保证相似度的前提下,将大的集合转化为短的签名。
  • Locality-Sensitive Hashing,关注可能来自相似文本的签名对。
  • 接下来具体介绍这三个步骤。

    Shingling

    一般特征矩阵需要自己获取,对于给定的文本,可以通过Shingling的方法构造特征集合。

    例如文本为”abcabe“,可以构造为k=2k=2k=2的集合,D={ab,bc,ca,be}D = \{ab, bc, ca, be\}D={ab,bc,ca,be},对于短的文本kkk一般取5,对于长的文本kkk取10。

    我们可以对集合进行hash,将一个长的字符串表示为一个4字节的数字,h(D)={1,3,2,7}h(D) = \{1, 3, 2, 7\}h(D)={1,3,2,7}

    得到文本的集合之后,就可以通过计算集合的相似度,从而判断两个文本的相似性。

    在计算相似度时,这里采用Jaccard similarity,sim(D1,D2)=∣D1∩D2∣∣D1∪D2∣sim(D_1, D_2) = \frac{|D_1\cap D_2|}{|D_1\cup D_2|}sim(D1,D2)=D1D2D1D2

    另外我们可以把集合表示为bit vector,这样求交集相当于AND运算,并集相当于OR运算。

    MinHashing

    一般文本的集合都非常大,MinHashing相当于降维,同时近似的保持相似度的准确度。

    MinHashing的具体做法时,对Shingles的集合进行随机打乱,bit vector为1的下标作为新的特征值。

    MinHash相等的概率刚好等于Jaccard Similarity值,Pr[hπ(D1)=hπ(D2)]=Jaccard(C1,C2)Pr[h_\pi(D_1) = h_\pi(D_2)] = Jaccard(C_1, C_2)Pr[hπ(D1)=hπ(D2)]=Jaccard(C1,C2)

    证明如下:

    对于两个document的集合来说,一共有三种情况:

    • 对应维度全为1,设有xxx个。
    • 对应维度只有一个1,设有y个。
    • 对应维度全为0。

    其中全为0的情况不影响MinHash的值,第一个非零行为第一类的概率为xx+y\frac{x}{x + y}x+yx

    另外从全排列考虑,第一行为第一类的情况有x(x+y−1)!x(x+y-1)!x(x+y1)!,全排列为(x+y)!(x+y)!(x+y)!,即对特征进行全排列后,MinHash相等的次数即为Jaccard Similarity。

    因此我们可以使用MinHash近似表示Jaccard Similarity,同时将长的vector压缩为短的签名。

    假设有K=100K=100K=100个hash函数,对于每一列CCC和hash函数kik_iki,初始化sig(C)[i]=∞sig(C)[i]=\inftysig(C)[i]=,对于每一行的非零值,如果ki(j)<sig(C)[i]k_i(j) < sig(C)[i]ki(j)<sig(C)[i],则更新sig(C)[i]=ki(j)sig(C)[i] = k_i(j)sig(C)[i]=ki(j)

    LSH

    通过MinHashing将特征矩阵转化为小的签名矩阵,接下来LSH将签名矩阵划分为bbb个band,每个band有rrr行,len(sig)=b×rlen(sig) = b\times rlen(sig)=b×r

    对于每个band,它们包含整体签名的一部分,将这部分签名通过hash映射到不同的桶中,如果两个签名相同它们就会映射到同一个桶中,经过b次映射,两个节点至少有一次被分到同一个桶中,我们就认为这两个节点的相似度更高。

    假设两个签名的相似度为ttt,那么在同一个band中每一行都相同的概率为trt^rtr,至少有一行不同的概率为1−tr1-t^r1tr,所有的band都不行同的概率为(1−tr)b(1-t^r)^b(1tr)b,至少有一个band的相同的概率为1−(1−tr)b1-(1-t^r)^b1(1tr)b

    另外bbbrrr是可调节的参数。

    参考文献

    Finding Similar Items

    Mining of Massive Datasets

    总结

    以上是生活随笔为你收集整理的Locality Sensitive Hashing的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。