LSHash(局部敏感哈希)

原载:http://cool.sinaapp.com
作者:junGle
原文网址:http://1.cool.sinaapp.com/?p=911


前文所说的minhash,比较的是jaccard相似度,基于两两来比较的话,如果文档数很大,比如:100w文档,根据排列组合公式可知,需要对比5000亿次。如果两篇文档签名相似度比较需要花费1微秒,那需要花费6天时间。

有啥办法能快速进行比较呢?有的,局部敏感哈希(locality-sensitive hashing, LSH)。

目标:减少对比次数

方法:通过多次哈希处理,让相似项尽可能落到同一桶中(确实相似的称为候选对,非相似的称为伪正例). 不相似的文档最好永远都不会哈希到相同的桶中。

————————————————————————————

一、MinHash的局部敏感哈希

以MinHash及其签名矩阵为例。

一个有效的哈希处理方法:将签名矩阵划分成多个band(行条, 行带),每个band由r行组成。对每个band,存在一个哈希函数能够将band中的每r个整数组成的列向量映射到某个大数目范围的哈希桶。对所有band使用相同的哈希函数,但是每个band都落在一个独立的桶数组中,因而保证了不同band间即使有列向量相同,也不会落到同一个桶中。

以12行的签名矩阵为例(每个band由3行组成):

假设:当且仅当两个向量相等时,才哈希到同一桶中

对于band1中, [0,2,1],有两列相同,因而落在相同桶中。[1,3,0]和[0,2,1]落在不同桶中。

整体上看,如果签名矩阵中的两列越相似,多个band中的向量相等的可能性也越大。

二、分析

假设:有b个行条(band),每个band都由r行组成,并假定对具体文档间的jaccard相似度为s。那么,文档的最小哈希签名矩阵中,某个具体行中的两个签名相等的概率等于s.

  • 1.在某个band中,所有行的两两签名相等的概率为  :s^r;     (幂运算)
  • 2.在某个band中,至少有一对签名不相等的概率为:1-s^r;
  • 3.在任何band中,任意一行的签名对都不相等的概率为:(1-s^r)^b;
  • 4.签名至少在一个band中全部相等的概率(成为候选对的概率):1-(1-s^r)^b;

成为候选对的概率:1-(1-s^r)^b。这个概率函数曲线(S曲线:S-curve)如下所示。上升最陡的地方对应的相似度就是阀值(它是b和r的函数,阀值的一个近似估计是:(1/b)^(1/r))。

当b=20, r=5时,成为候选对的概率为:1-(1-s^5)^20, s的取值(相似程度)决定了候选对“抱团”的质量。

可以看到,当s=0.8时,1-(0.8)^5为0.328,其概率可以达到0.9996,也就是说,如果认为两篇文档的相似度达80%时,如果有3000个对,大致只有1个对相似度为80%的对不会成为候选对(3000*(1-0.9996)=1.2左右)。

【简单介绍下Jaccard距离】

d(x,y)=1-SIM(x,y)

三、局部敏感函数

3.1  (d1, d2, p1, p2)-sensitive

我们需要一个判定函数,函数f判定f(x,y)的两个输入项是否为候选对。

  • x和y是一个候选对,用f(x)=f(y)表示
  • x和y不是候选对,用f(x)≠f(y)表示

多个这种形式的函数集合构成一个“函数族”F。函数族F中的每个函数f,都基于特征矩阵的一个可能行排列转换而成。

令d1<d2是定义在某个距离测度d下的两个距离值。如果一个函数族F中的每一个函数f都满足下列条件:

(1)如果d(x,y)≤d1, 那么f(x)=f(y)的概率至少为p1;

(2)如果d(x,y)≥d2,那么f(x)=f(y)的概率最大是p2.

则称F为(d1,d2,p1,p2)-敏感的函数族;

有点“马太效应” 的味道在里头。

对于MinHash来说,换一个方法解释最小哈希函数h:当且仅当h(x)=h(y)时,x和y是一个候选对。(很容易理解)

于是有结论:

对于任意d1,d2,0≤d1<d2≤1,最小哈希函数族是 (d1, d2, 1-d1, 1-d2)-敏感 的。

推导:如果x,y的jaccard距离d(x,y)≤d1, 那么SIM(x,y)=1-d(x,y)≥1-d1。由x,y的jaccard相似度等于h(x)=h(y)的概率可知,上述p1≥SIM(x,y)≥1-d1。 对d2的推导类似。

设d1=0.3, d2=0.6,可以断言最小哈希函数族是 (0.3, 0.6, 0.7, 0.4)-sensitive 的。

也就是说,

如果x和y的jaccard距离不大于0.3, 那么x,y哈希到相同值的概率至少为0.7.

如果x和y之间的jaccard距离不小于0.6,那么最小哈希函数将x和y哈希到相同值的概率至多为0.4.

3.2  与构造:(d1, d2, p1^r, p2^r)-sensitive

F ‘ 的成员函数由r个F成员函数组成。=> 降低所有概率

3.3 或构造:(d1, d2, 1-(1-p1)^b, 1-(1-p2)^b)-sensitive

F ‘ 的成员函数f由b个F中的成员函数{f1, f2, f3, … , fb}组成。=> 提升所有概率

===========================================

simhash的汉明距离

4. 利用 Simhash 查找相似文档

已知两篇文档 Simhash 值之间的海明距离越小,Jaccard 相似度越高,假设我们能够接受的最大海明距离为K,根据上面对 LSH 的描述,我们可以实现一种快速查找相似文档的方法:

  1. 对文档集中的每一篇文档:
    • 计算一个 N 位的 Simhash 值,
    • 对值按位做 T 次随机排列,得到 T 个 N 位的值,
    • 对每个值取前 P 位生成 Key 存入词典,Value 为原 Simhash 值;
  2. 查找时:
    • 对查找文档生成一个 N 位的 Simhash 值,
    • 对值按位做 T 次随机排列,得到 T 个 N 位的值,
    • 对每个值取前 P 位生成 Key 查找词典,计算原 Simhash 值和 Value 间的海明距离,
    • 如果小于 K,则加入到结果中。

假设文档集中有一篇文档和查找文档的 Simhash 值间海明距离为 K,则上述查找过程能够找到这个文档(即Key 命中)的概率:

  1. 对某个排列,前 K 位相同的概率为:(1-K/N)**P
  2. 对某个排列,前 K 位不相同的概率为:1 - (1-K/N)**P
  3. 对 T 次排列,前 K 位都不相同的概率为:(1 - (1-K/N)**P)**T
  4. 对 T 次排列,前 K 位至少有一次相同的概率为:1 - (1 - (1-K/N)**P)**T
    因此, Key 命中的概率为 1 - (1 - (1-K/N)**P)**T

例如当 N=64,P=16,K=6,T=8 时,P = 0.791520

2.汉明距离
计算x,y里面不同bit的个数。
这个也很简单,hash函数集合F中, fi(x) = xi即可
其实这个和simhash的后续处理一致

对于haming距离

假设两条相似消息的simhash每一位相同的概率为p
从64位里随机选取a位
这a位数相同的概率是p^a,不同的概率就是1-p^a
进行b次选取,每次取的a位数都不相同的概率就是(1-p^a)^b
这b次选取中有1次或以上a位数相同的概率是y=1-(1-p^a)^b

若汉明距离阀值定为8(<8即相似),那么对于两条相似的消息,p=(64-8)/64=0.875
然后,我们可以定义b个不同的0-64的排列,每个排列选前a个数,表示“随机选取a位,组成一个a位数”。
对每条消息,都计算b次这样的a位数,作为b个索引。
假设a=16,b=10,若一条消息是命中相似的,则有y=1-(1-0.875^16)^10 = 0.715=71%的概率可以通过以上方法建立的索引找到与其相似的消息

假设有100w消息,大约每条消息只要经过100w/(2^16)*10=152次汉明距离计算就有一定概率找到确实与其相似的消息,计算量降低了不少.


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值