Locality Sensitive Hashing

今天介绍Locality Sensitive Hashing(LSH)。不同以往,这次我先放参考文献,因为本文都是基于这些参考文献的个人理解和消化,强烈推荐先看我的再去看参考文献,以便能更好的理解参考文献。

References

Introduction

In computer science, locality-sensitive hashing (LSH) is an algorithmic technique that hashes similar input items into the same “buckets” with high probability. (The number of buckets is much smaller than the universe of possible input items.) Since similar items end up in the same buckets, this technique can be used for data clustering and nearest neighbor search. Alternatively, the technique can be seen as a way to reduce the dimensionality of high-dimensional data; high-dimensional input items can be reduced to low-dimensional versions while preserving relative distances between items.

Challenge

Even on the best hardware, comparing all pairs is out of the question. This produces an at best complexity of O ( n 2 ) O(n^2) O(n2). Even if comparing a single query against the billions of samples, we still return an at best complexity of O ( n ) O(n) O(n).

这很容易理解,对于大规模数据的场景要找相近的数据就显得特别困难,因此本文讲详细介绍Locality Sensitive Hashing(LSH)来解决这种问题。

Locality Sensitive Hashing

LSH function

LSH有很多变体,这里我们仅考虑最传统的方法,该方法分为3步:shingling, MinHashing and the final banded LSH function。为了便于理解,我先从LSH function开始讲起。

Hash Table

这里先插播一点哈希相关知识,因为我发现我不知道人家文章里词啥意思。大白话版(源自面试官:哈希表都不知道,你是怎么看懂HashMap的?):哈希表就是通过一个映射函数f(key)将一组数据散列存储在数组中的一种数据结构。在这哈希表中,每一个元素的key和它的存储位置都存在一个f(key)的映射关系,我们可以通过f(key)快速的查找到这个元素在表中的位置。
举个例子方便理解,有一组数据:[19,24,6,33,51,15],我们用散列存储的方式将其存储在一个长度为11的数组中。采用除留取余法,将这组数据分别模上数组的长度(即f(key)=key % 11),以余数作为该元素在数组中的存储的位置。则会得到一个如下图所示的哈希表:
在这里插入图片描述
此时,如果我们想从这个表中找到值为15的元素,只需要将15模上11即可得到15在数组中的存储位置。

Hash Collision

知道了Hash Table后理解Hash Collision就比较简单了,可以看出对于上述的存储方法,总会有那么一些不同数据会被存储在相同的位置,这就是Hash Collision。
举个例子,假如我们向上面的数据中再插入一些元素,插入后的数据为:[19,24,6,33,51,15,25,72],新元素25模11后得到3,存储到3的位置没有问题。而接下来我们对72模11之后得到了6,而此时在数组中6的位置已经被其他元素给占据了。“72“只能很无奈的表示我放哪呢?
在这里插入图片描述
常见的Hash Collision解决方法有(详见面试官:哈希表都不知道,你是怎么看懂HashMap的?):

  • 开放定址法
  • 再哈希法
  • 建立公共溢出区
  • 链地址法

LSH Hash Collision

现在你会发现,原来需要被解决的Hash Collision有了新的用处,他可以被设计用来存放相近的样本,而设计映射函数成了一个最关键的部分,下图展示了LSH Hash Function。

In LSH, we want to maximize collisions, although ideally only for similar inputs. An LSH function aims to place similar values into the same buckets.

在这里插入图片描述
这里再给出Typical Hash Function进行对比,方便理解。
在这里插入图片描述

Different LSH Function

这里不再赘述,怕讲错,有兴趣的可以看A Simple Introduction to Locality Sensitive Hashing (LSH)

  • Bit Sampling LSH
  • Euclidean and Manhattan LSH
  • Clustering LSH

Shingling & MinHashing

Shingling - Wikipedia
第一步我们首先要把数据转成key值才能进行后续的操作,这里为了方便起见,我们拿文本数据来举例子:

Shingling

k-Shingling is the process of converting a string of text into a set
of ‘shingles’. The process is similar to moving a window of length k
down our string of text and taking a picture at each step. We collate
all of those pictures to create our set of shingles.

给一个形象的例子:
在这里插入图片描述
有了这些shingles,我们接下来要把他们转化成sparse vectors,先把所有这些shingles组成一个vocabulary。然后对相应的词向量进行one-hot编码
在这里插入图片描述

MinHashing

有了上述的sparse vectors后,我们需要思考怎么convert sparse vectors into dense vectors,注意,这部分比较难理解,可以参考Min Hashing
首先先将vocabulary随机打乱,然后进行one-hot编码,再记录下该打乱顺序下每一列第一个为1的元素值。
在这里插入图片描述
在这里插入图片描述
这里用 J S ( S i , S j ) JS(S_i, S_j) JS(Si,Sj) 估 计 J S ^ ( S i , S j ) 估计\hat{JS}(S_i, S_j) JS^(Si,Sj),其中Jaccard similarity的计算方式:
在这里插入图片描述
其他表示形式:
在这里插入图片描述
这里证明 E [ J S ^ ( S i , S j ) ] = J S ( S i , S j ) E[\hat{JS}(S_i, S_j)]=JS(S_i, S_j) E[JS^(Si,Sj)]=JS(Si,Sj)为什么可以这样:
Proof. There are three types of rows.
(1) There are x rows with 1 in both column
(2) There are y rows with 1 in one column and 0 in the other
(3) There are z rows with 0 in both column

S 1 S_1 S1 S 2 S_2 S2
11
01
10
00

可能目前你还是一头雾水,为什么有四种状态,别着急看了下面这张图就明白了(我也是这么懵逼过来的)
在这里插入图片描述
结合这张图,你可以看到他是对原始的两个set数据进行one-hot编码, x x x就是相同的位置都有元素存在,也就是 m ( S i ) = m ( S j ) m(S_i)=m(S_j) m(Si)=m(Sj),而 y y y是相同的位置仅有一个元素存在,更普遍的 z z z是相同位置上一个元素都没有。因为编码的值是稀疏的,所以就有 z > > x , y z>>x,y z>>x,y,且总行数为 x + y + z x+y+z x+y+z
现在Jaccard similarity is precisely J S ( S i , S j ) = x x + y JS(S_i, S_j)=\frac{x}{x + y} JS(Si,Sj)=x+yx为什么分母只有 x + y x + y x+y就好理解了。
接着就是最重要的部分了:
在这里插入图片描述
可以发现如果对 ∣ A ⋃ B ∣ |A \bigcup B| AB进行采样,因为我们知道这里面的元素都是来自哪个集合的,因此也就知道了 ∣ A ⋂ B ∣ |A \bigcap B| AB的数量,而此时的 ∣ A ⋂ B ∣ ∣ A ⋃ B ∣ \frac{|A \bigcap B|}{|A \bigcup B|} ABAB是对原始Jaccard similarity的一次估计。
这里这个Ben Langmead老师还给出了另一种indirect估计Jaccard similarity的方式,其实是对之前的相似性度量进行了一个变形:
在这里插入图片描述
当然这是不严谨的证明方法,这里贴一个严谨的证明估计误差的方法:
在这里插入图片描述
证明前面的部分其实我上面讲过了,主要就是他进行了 K K K次采样,然后计算了采样和真实值的一个误差 Y t = 1 k ( X t − J S ( S i , S j ) ) Y_t=\frac{1}{k}{(X_t-JS(S_i, S_j))} Yt=k1(XtJS(Si,Sj))最后这个Theorem 3.1.2不知道是啥(大哭),然后就证明出来了。最后奉上计算MinHash的步骤:
在这里插入图片描述

Banding

The banding method solves this problem by splitting our vectors into sub-parts called bands b. Then, rather than processing the full vector through our hash function, we pass each band of our vector through a hash function.

在这里插入图片描述
在这里插入图片描述
综上所述,总的流程可以概括如下:
在这里插入图片描述
或者这个:
在这里插入图片描述

Testing LSH

James Briggs这位大哥还给出了练习代码pinecone-io/examples,真是太赞了!!!(可惜我没看)

Applications of LSH

  • Near Duplication Detection: LSH is commonly used to deduplicate large quantities of documents, webpages, and other files
  • Genome Study: LSH can be used to identify similar gene expressions in genome databases
  • Image and Video Search: Large-scale searching can be deployed using LSH
  • Video Fingerprinting: In multimedia technologies, LSH is widely used as a fingerprinting technique A/V data

Conclusion

其实在MinHashing部分和最后的band&hash还是不太理解,这个下次如果有机会用上LSH的时候我再去仔细研究下代码,并回来补充,当然如果有大佬明白的也不妨在评论区点播一下俺。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值