Approximate Nearest Neighbor Search(ANNS)
在一个给定的空间(或集合)中找到距离兴趣(或目标)对象最近的邻居,这个问题在多种领域都是非常基本而重要的, 如生物、医学、地理、机器人、互联网等等只要涉及数据检索、机器学习、大规模数据处理等基本都会需要。特别当数据量或(和)维度增大时,如何快速高效地找到最近邻尤其重要,甚至可能是整个链路可用与否的关键,。此问题称为最近邻检索(Nearest neighbor search,NNS)。ANNS问题其实就是需要为给定的集合构建一种数学模型(或更具体地,称为数据结构),当给定一个检索对象时,可以在集合快速找到与其最近的邻居。
一般地, 设集合\(\mathbb{U}\), 与在其上的距离测度(distance measure) \(D\), NNS问题即构建数据结构,对于给定的\(S\subset \mathbb U, q \in S\),找到$ a \in S$,使得:
并称对于测度\(D\),在\(S\)中 a是q 的最近邻[1]。
然而在有些场景,精确检索到最近邻成本非常高,甚至可能无法满足实际生产需求,或者有些场景并不是真正需要最近邻结果,近似的也能满足需要,比如在推荐场景中,只需给用户推荐可能需要的产品。这样
一般地, 设集合\(\mathbb{U}\), 与在其上的距离测度(distance measure) \(D\), ANNS问题即构建数据结构,对于给定的\(S\subset \mathbb U, q \in S\),找到$ b \in S$,使得:
其中\(c> 1\), \(a\in S\)是真实的最近邻,则称为对于测度\(D\),在\(S\)中 b是q 的近似最近邻[2]。根据不同需要,最终得到的b可以不只一个。
ANN常用的方法主要有以下几类:
- 树方法,如 KD-tree,Ball-tree,Annoy
- 哈希方法,如 Local Sensitive Hashing (LSH)
- 矢量量化方法,如 Product Quantization (PQ)
- 近邻图方法,如 Hierarchical Navigable Small World (HNSW)
树方法
kd-tree
kd-tree
是树方法的经典算法,其是二分搜索树在多维空间的推广。二分搜索树检索迅速的原因是规定将数据中大于当前节点数据的方在一侧(比如右子树),而不小于的放在另一侧(比如左子树),这样检索数据时,即可获得logn
的速度。kd-tree 也类似,只不过二分搜索树一维空间搜索推广到n维空间。如同x-y轴坐标系将二维空间分成四个部分一样, n维空间也可这样划分。然后,规定将大于分割点的数据放在某一侧(比如右子树),不小于分割点的数据放在另一侧(比如左子树)。