在做海量高维向量相似度快速计算比赛时,对最近邻搜索方法做了一些泛读和总结。主要以下分为几大类。
一是基于树形的高维索引,如kd-tree,R-tree等,但当维度较高时,查询性能急剧下降。
二是基于map-reduce方法,选择合适个数的中心点,相当于一个聚类操作,将一个中心点定义为一个cell。使用多个计算节点将查找集和被查找集同时映射到距离最近的中心点,也就是对应的cell中。对每个cell中的点进行reduce,计算cell内部的一些数据用于后续处理,如cell内向量总数等。为了减少错误率,与查找向量最近的向量可能不在同一个cell中,采用启发式复制的方式,从相邻的cell中复制向量进行距离计算。更多的优化细节见论文
Comparing MapReduce-Based k-NN Similarity Joins on Hadoop for High-Dimensional Data
这种方法适合查找集规模很大时,并行计算会产生较优的效果。
三是facebook提出的矢量量化方法faiss具有比较好的效果且支持数据集的动态增删。
四是哈希方法,即本文的重点,局部敏感散列(LSH),其核心思想是:设计一种特殊的hash函数,使得2个相似度很高的数据以较高的概率映射成同一个hash值,而令2个相似度很低的数据以极低的概率映射成同一个hash值。我们把这样的函数,叫做LSH。根据这次比赛的数据规模我们最终选择这个方法。网上对于LSH介绍的博客已经有很多,以及对于欧式距离量度的p-stable哈希都有了比较详细的介绍(可参考这篇文章