赞
踩
转自:近似最近邻搜索算法 ANNOY(APPROXIMATE NEAREST NEIGHBORS OH YEAH)
在搜索的业务场景下,基于一个现有的数据候选集(dataset),需要对新来的一个或者多个数据进行查询(query),返回在数据候选集中与该查询最相似的 Top K 数据。
最朴素的想法就是,每次来了一个新的查询数据(query),都遍历一遍数据候选集(dataset)里面的所有数据,计算出 query 与 dataset 中所有元素的相似度或者距离,然后精准地返回 Top K 相似的数据即可。
但是当数据候选集特别大的时候,遍历一遍数据候选集里面的所有元素就会耗费过多的时间,其时间复杂度是 O(n)
因此,计算机科学家们开发了各种各样的近似最近邻搜索方法(approximate nearest neighbors)来加快其搜索速度,在精确率和召回率上面就会做出一定的牺牲,但是其搜索速度相对暴力搜索有很大地提高。
在近似最近邻搜索(ANN)领域,有很多开源的算法可以使用,包括但不限于:
Annoy 的算法思想
用 n 表示现有的文档个数,如果采用暴力搜索的方式,那么每次查询的耗时是 O(n)
采用合适的数据结构可以有效地减少查询的耗时,在 annoy 算法中,作者采用了二叉树这个数据结构来提升查询的效率,目标是把查询的耗时减少至 O(ln(n))
刚开始的时候,在数据集中随机选择两个点,然后用它们的中垂线来切分整个数据集,于是数据集就被分成了蓝绿两个部分。然后再随机两个平面中各选出一个顶点,再用中垂线进行切分,于是,整个平面就被切成了四份。
用一颗二叉树来表示这个被切分的平面就是:
后续继续采用同样的方式进行切分,直到每一个平面区域最多拥有 K 个点为止。当 K = 10 时,其相应的切分平面和二叉树如下图所示。
K = 10 的时候,每个子平面最多 10 个点
下面,新来的一个点(用红色的叉表示),通过对二叉树的查找,我们可以找到所在的子平面,然后里面最多有 K = 10 个点。从二叉树的叶子节点来看,该区域只有 7 个点。
在 ANN 领域,最常见的两个问题是:
作者用了两个技巧来解决这个问题:
Annoy 算法原理:
构建索引:建立多颗二叉树,每颗二叉树都是随机切分的;
查询方法:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。