【大数据】网页相似度-Shingling、MinHash与LSH

给定一个文档"a rose is a rose is a rose",要计算出一个特征用于做网页对比,从而和其他文档计算相似度。

Shingling

和k-gram一样,按照长度为4进行划分,得到{"a rose is a", "rose is a rose", "is a rose is", "a rose is a", "rose is a rose"},因为要得到集合,去重得到{"a rose is a", "rose is a rose", "is a rose is"}。

然后就可以对比了,通常对于两个集合计算器Jaccard系数,设文档1得到集合S1,文档2得到几何S2。则其相似度用Jaccard系数衡量:

Shingling方法虽好,但是计算两个集合的交集和并集要逐一对比两个集合的Shingling,计算量极大。

MinHash

MinHash方法用来估计Jaccard系数,基本思想是“两个集合Jaccard系数"等于“两个集合MinHash值相等的概率”。

MinHash里的“Hash”函数,其实就是对文档矩阵按行重新排列,然后自上向下找出每一列中,第一次出现非零元素的行数,然后形成一个向量,又叫签名(signature)向量。

记原文档矩阵m行n列,重复执行k次这样的操作,形成一个k行n列的签名矩阵(signature matrix)。

要计算文档i 和文档j 的相似度,只需要对比signature matrix的第i列和第j列,对应相同元素的比例值就是相似度。

例如下面的案例:

import numpy as np
def shuffle(A, p):
    new_A = []
    for i in range(len(p)):
        new_A.append(A[p[i]-1])
    return np.array(new_A)

A = [
    [1,0,1,0],
    [1,0,0,1],
    [0,1,0,1],
    [0,1,0,1],
    [0,1,0,1],
    [1,0,1,0],
    [1,0,1,0]
]
p1 = [1,3,7,6,2,5,4]
p2 = [4,2,1,3,6,7,5]
p3 = [3,4,7,6,1,2,5]
print('----p1----')
print(shuffle(A, p1))
print('----p2----')
print(shuffle(A, p2))
print('----p3----')
print(shuffle(A, p3))

矩阵A按照排序p2重新排列的结果如下,其signature vector 为[2,1,3,1]

[[0 1 0 1]
 [1 0 0 1]
 [1 0 1 0]
 [0 1 0 1]
 [1 0 1 0]
 [1 0 1 0]
 [0 1 0 1]]

p1,p2,p3三次Hash操作得到的signature matrix为

[[1 2 1 2]
 [2 1 3 1]
 [3 1 3 1]]

 计算相似度S(1,3)=0.667, S(2,4)=1, S(1,2)=0

LSH(Local Sensitive Hashing)

局部敏感哈希,就是把signature按行划分出n个bands,每个bands有r行,但是每次计算一个band的signature matrix,要求相似的列在band中对应相等的元素必须大于某一值才算,然后映射到不同的bucket。同一个bucket里面的文档是相似的。

Example如下:

 

posted @ 2022-12-01 23:50  倦鸟已归时  阅读(336)  评论(0编辑  收藏  举报