局部敏感哈希——冗余文档发现

冗余文档发现

具体步骤

第一步:Shingling

目的:将文档转化为集合

一个文档的一个k-Shingle是出现在该文当中的k个tokens构成的序列

为了对长的shingles压缩,可以对它们进行哈希,哈希成一个整数(4字节)

用一个文档的所有k-shingles的哈希值构成集合来表示该文档

Shingles的压缩

例子:k=2;文档D=abcab

2-shingles的集合:S(D)={ab,bc,ca}
对shingles做哈希:h(D)={1,5,7}

在实际中k常常是8,9或10

shingle的好处:

相似为文档往往有很多共同的shingles
改变一个单词往往只会影响和这个单词距离不超过k-1的k-shingles

文档 D 1 D_1 D1​的k-shingles集合是 C 1 = S ( D 1 ) C_1=S(D_1) C1​=S(D1​)

Jaccard相似度:
s i m ( D 1 , D 2 ) = ∣ C 1 ∩ C 2 ∣ / ∣ C 1 ∪ C 2 ∣ sim(D_1,D_2)=|C_1∩C_2|/|C_1∪C_2| sim(D1​,D2​)=∣C1​∩C2​∣/∣C1​∪C2​∣

Jaccard距离:

d ( D 1 , D 2 ) = 1 − ∣ C 1 ∩ C 2 ∣ / ∣ C 1 ∪ C 2 ∣ d(D_1,D_2)=1-|C_1∩C_2|/|C_1∪C_2| d(D1​,D2​)=1−∣C1​∩C2​∣/∣C1​∪C2​∣

局部敏感哈希——冗余文档发现

第二步:最小哈希(针对Jaccard相似度)

最小哈希:将大集合转化为小的签名同时保留其相似度。

签名:表示集合的较短的整数向量,能表示集合间的相似度。

思想是:将每一列C“哈希”成一个小的签名h©,使得sim(C1,C2)等于签名的h(C1)和h(C2)的“相似度”。

目标是:找到一个哈希函数h(·),使得:

如 果 s i m ( C 1 , C 2 ) 大 , 则 h ( C 1 ) = h ( C 2 ) 的 概 率 大 如果sim(C1,C2)大,则h(C1)=h(C2)的概率大 如果sim(C1,C2)大,则h(C1)=h(C2)的概率大
如 果 s i m ( C 1 , C 2 ) 小 , 则 h ( C 1 ) ≠ h ( C 2 ) 的 概 率 大 如果sim(C1,C2)小,则h(C1) ≠ h(C2)的概率大 如果sim(C1,C2)小,则h(C1)​=h(C2)的概率大

想法:将文档哈希到桶里。期望“绝大多数”近似冗余的文档被哈希到同一个桶里。
局部敏感哈希——冗余文档发现π为随机选择策略

对所有列进行应用几个随机挑选的排列,从而对每一个列构建一个签名。

输出结果是一个签名矩阵:列=集合(文档),行=该列的若干最小哈希值

局部敏感哈希——冗余文档发现

第三步:局部敏感哈希(LSH:Local Sensitive Hash)

目标:发现Jaccard相似度至少为s的文档对(给定相似度阈值,例如,s=0.8)

LSH的基本思想:用一个函数 f ( x , y ) f(x,y) f(x,y)来判断 x x x和 y y y是否是一个候选对:其相似度需要进行计算的元素对。

对于最小哈希矩阵:

将签名矩阵 M M M的列哈希到多个桶里
被哈希到同一个桶里的文档是一个候选对

局部敏感哈希——冗余文档发现
步骤:

  1. 将签名矩阵 M M M划分成b个行条,每个行条有r行
  2. 对于每个行条,将它对应每一列的内容哈希到包含k个桶的哈希表中(让k尽可能大)
  3. 候选对是≥1和行条被哈希到同一个桶的列队
  4. 通过调整r和b,可以捕捉绝大多数相似对,且包含很少不相似对

通过挑选:

最小哈希的个数( M M M的行数),行条个数b和每个行条的行数r来平衡:假阳性/假阴性

局部敏感哈希——冗余文档发现

上一篇:【ybt高效进阶2-3-2】重复子串


下一篇:Educational Codeforces Round 83 --- F. AND Segments