![e4105c4646d35ecc8e220b28f2015c2f.png](https://i-blog.csdnimg.cn/blog_migrate/eb8dc4ac9bfffb89acaf23fec9368e56.jpeg)
本文是参考文献[1-5]的知识点总结。
最大内积搜索算法,英文是Maximum Inner Product Search,简称MIPS。
随着深度学习中embedding的应用,最大内积搜索算法使用的也越来越广。比如之前莫比乌斯: 百度的下一代query-ad匹配算法所讲的广告系统,推荐系统以及基于深度学习的语言模型等,都会使用计算最大内积的方法来进行目标数据的预筛选。而预筛选的好坏也直接影响到最终的结果。
那么在大规模数据的条件下,如何进行快速的最大内积搜索呢?暴力算法自然是直接遍历,时间复杂度是O(nd),n是样本数,d是样本维度。
目前主流的方法有三种:
- 基于内积上界去做过滤,典型的方法如Cauchy-Schwarz不等性。这一点暂时先不关注。
- 将MIPS问题给转化成最近邻搜索NNS(Nearest Neighbor Search)问题,这样就可以采用NNS上的方法,包括基于图的搜索以及基于哈希的搜索等。
- 直接将NNS上的方法应用在MIPS上。
本文主要展开讲后两点的方法。
最近邻搜索NNS
最近邻搜索跟MIPS其实很像,区别在于Metric不一样,最近邻搜索一般使用l2-Norm或者余弦距离来进行计算,而MIPS则是内积。
其中有个隐含的联系就是如果||x|| = 1, ||y|| = 1。那么余弦距离和内积是等价的。这点我们先放在这里。后面会用到。
我们先来介绍一个概念,沃罗诺伊块(Voronoi cell):
![8da02b6806e47be5ed0e80d59c6f89b7.png](https://i-blog.csdnimg.cn/blog_migrate/48500c3d5bb49ddee7bc44d538e5f4fa.png)
沃罗诺伊图的概念很简单,在d维空间中,xk这个点的沃罗诺伊块就是所有的距离它的距离比其他x都要小的点的集合。有同学可能会说,公式里是大于号,为什么是距离要小呢?在这里是为了定义的通用性,我们可以给距离公式加一个负号。再看一张图来直观的看一下沃罗诺伊块:
![7ca1a9db5782adb76c1b779c9d0c0f50.png](https://i-blog.csdnimg.cn/blog_migrate/437ecf7dedac125aa2dc1eb1c1e0b27c.jpeg)
图中每一个不同颜色的块都是对应起区域内黑点的沃罗诺伊块。距离计算公式是-||x - y||。可以注意到相邻的两个块之间的分界线一般是对应的两个点的连线的中垂线。
有了这个沃罗诺伊图之后,我们再来定义一个概念,那就是Delaunay Graph(德劳内图)。
![66e39888548f9e56f610594d5eb614de.png](https://i-blog.csdnimg.cn/blog_migrate/1d73b853e74d2715e528b8089d352a1e.png)
定义很长,翻译过来就是如果两个点的沃罗诺伊块相邻,那么这两个点之间就建立一条边。
这两个概念的名字都非常的拗口,但是大家不要被吓到,就是两个概念而已,喜欢的话,可以改成悟空块,八戒图。Just Joke.
在有了这个德劳内图之后,要想找最近邻,就可以使用一个贪心算法来解决:
![0fb6e8593332157658ed09c204d0c1ce.png](https://i-blog.csdnimg.cn/blog_migrate/46eb9594c77653dab8228691e821b970.jpeg)
算法的大体含义是对于每个query,从随机的一个点开始找,如果相邻的点的距离更小,那么就移到距离最小的相邻点继续找,直到相邻点的距离都比当前点大。
这样的话,算法找到是局部极值,但是在德劳内图的条件下,局部极值和全局机制是等价的