紧跟上一篇博客 k-shingles与minhash技术,我们使用minhash压缩内容量较大的文档,但是文档相互之间的相似性计算仍然比较麻烦,因为两两之间的文档pairs太多了。有时候我们只需要最相似的文档pairs,没有必要计算所有pairs,为此我们引入LSH(locality-sensitive hashing)技术。
LSH的基本思想
将原始数据空间中的两个相邻数据点通过相同的映射后,这两个数据点在新的数据空间中仍然相邻的概率很大,而不相邻的数据点被映射到同一个桶的概率很小。也就是说,如果我们对原始数据进行一些hash映射后,我们希望原先相邻的两个数据能够被hash到相同的桶内,具有相同的桶号。因此,LSH算法使用的关键是针对某一种相似度计算方法,找到一个具有以上描述特性的hash函数。如果能够找到这样一些hash functions,使得经过它们的哈希映射变换后,原始空间中相邻的数据落入相同的桶内,那么我们在该数据集合中进行近邻查找就变得容易,只需要将查询数据进行哈希映射得到其桶号,然后取出该桶号对应桶内的所有数据,再进行线性匹配即可查找到与查询数据相邻的数据。如果不相似的pairs哈希到同一个桶中,这样会使结果的false positive增加;反之,如果真正相似的pairs哈希到不同的桶中,那么会使结果的false negative增加。我们的目标是让false positive和false negative的比例尽可能的小。
LSH直观解释
locality sensitive:彼此相近的数据点能够映射到相似的哈希值(以很高的概率放入相同哈希桶中)。
在上图中,有红色和黄色的圆圈,表示二维空间中的数据点,下面利用LSH找到它们的cosine相似性。灰色的线表示被选中的随机平面。如果数据点落在灰色线条的上面,用0(白色)表示,否则用1(黑色)表示。一旦选中一组平面,就可以根据平面对数据点进行编码,得到一个签名。数据点的签名角度的差异和实际的差异程度非常接近,因为夹在两个点之间的一个平面会给出1bit的差异。
如上图所示,只用6bits就可以表示两个数据点,这就是原始数据的LSH哈希值。由于两个数据点的签名只有1位不同,两个哈希值之间的海明距离为1,根据签名的长度,可以计算出夹角的相似性。
Banding技术
对于minhash 的signature矩阵,将其分成b个bands,每个band有r行组成,然后使用hash函数将每个band中每一列哈希到一个很大的hash table中,只要hash table中桶的数量足够大,那么地址碰撞的机率是非常小的。