本文提要
在这篇博客中,我将首先介绍一个广泛被使用的Top-k查询操作和当前学术界加快这一查询的做法。第二,我将分析LSH如何实现加快查询,并介绍LSH的定义和给出一个例子来分析。最后,我最早关于LSH的论文以及它们的缺点,并引出后续相关论文的优化和缺点。
背景
Top-k查询,也就是给定一个目标 o o o,在一个数据集中找出和目标o最相似的k个目标。这一查询在各类应用中被广泛使用,例如聚类算法等。以下几个是实现方案:
暴力算法:实现Top-k查询,也就是计算 o o o和数据集中每一个目标的相似度,然后排序找出前k个。我们假设一个房子特征目标o={
a 0 = a_0= a0=地理, a 1 = a_1= a1=房子尺寸, a 2 = a_2= a2=楼层,…, a m = a_m= am=新旧}(这经常被用在机器学习中),典型地采用欧式距离计算两个目标 o 1 = { a 0 , a 1 , . . . a m } , o 2 = { b 0 , b 1 , . . . , b m } o_1=\{a_0,a_1,...a_m\},o_2=\{b_0,b_1,...,b_m\} o1={
a0,a1,...am},o2={
b0,b1,...,bm}的相似度: d ( o 1 , o 2 ) = ( a 0 − b 0 ) 2 + ( a 1 − b 1 ) 2 , . . . , ( a m − b m ) 2 d(o_1,o_2)=\sqrt{(a_0-b_0)^2+(a_1-b_1)^2,...,(a_m-b_m)^2} d(o1,o2)=(a0−b0)2+(a1−b1)2,...,(am−bm)2,这一时间复杂度是 O ( m ) O(m) O(m),假设数据集大小为 n n n,那么执行一次Top-k的复杂度为 O ( m n ) + O ( l o g ( n ) ) O(mn)+O(log(n)) O(mn)+O(log(n)),其中 m m m是数据维度,后者是排序复杂度。
显然,这一复杂度是十分高昂的,特别是在数据集的维度 m m m很大时,一次查询的时间会很长。
空间划分算法:为了改善查询效率,研究学者提出了包括Kd-Tree,R-Tree,PM-Tree等各类空间划分算法,但不幸的是,他们只适用于 m m m较小的情况下,典型地10~15以下。
在数十年的研究之后,学者发现要想准确地找到所有Top-k结果,高额的时间开销是难以避免的,因此近似的(approximate)Top-k查询的概念被提出 。具体而言,近似Top-k查询找到的k个结果不一定是精确Top-k查询的结果。一般而言,我们用Recall来衡量近似Top-k查询结果的质量:
Recall = ∣ R ∩ R ∗ ∣ ∣ R ∗ ∣ \text {Recall}=\frac{\left|R \cap R^{*}\right|}{\left|R^{*}\right|} Recall=∣R∗∣∣R∩R∗∣
其中, R = { o 0 , o 1 , . . . , o k } R=\{o_0,o_1,...,o_k \} R={
o