近似最近邻算法-annoy解析
转自https://www.cnblogs.com/futurehau/p/6524396.html
Annoy是高维空间求近似最近邻的一个开源库。
Annoy构建一棵二叉树,查询时间为O(logn)。
Annoy通过随机挑选两个点,并使用垂直于这个点的等距离超平面将集合划分为两部分。
如图所示,图中灰色线是连接两个点,超平面是加粗的黑线。按照这个方法在每个子集上迭代进行划分。
依此类推,直到每个集合最多剩余k个点,下图是一个k = 10 的情况。
相应的完整二叉树结构:
随机投影森林。
一个思想依据是:在原空间中相邻的点,在树结构上也表现出相互靠近的特点,也就是说,如果两个点在空间上相互靠近,那么他们很可能被树结构划分到一起。
如果要在空间中查找临近点,我们可以在这个二叉树中搜索。上图中每个节点用超平面来定义,所以我们可以计算出该节点往哪个方向遍历,搜索时间 log n
如上图,我们找到了七个最近邻,但是假如我们想找到更多的最近邻怎么办?有些最近邻是在我们遍历的叶子节点的外边的。
技巧1:使用优先队列
如果一个划分的两边“靠得足够近”(量化方式在后面介绍),我们就两边都遍历。这样就不只是遍历一个节点的一边,我们将遍历更多的点
我们可以设置一个阈值,用来表示是否愿意搜索划分“错”的一遍。如果设置为0,我们将总是遍历“对”的一片。但是如果设置成0.5,就按照上面的搜索路径。
这个技巧实际上是利用优先级队列,依据两边的最大距离。好处是我们能够设置比0大的阈值,逐渐增加搜索范围。
技巧2:构建一个森林
我们能够用一个优先级队列,同时搜索所有的树。这样有另外一个好处,搜索会聚焦到那些与已知点靠得最近的那些树——能够把距离最远的空间划分出去
每棵树都包含所有的点,所以当我们搜索多棵树的时候,将找到多棵树上的多个点。如果我们把所有的搜索结果的叶子节点都合在一起,那么得到的最近邻就非常符合要求。
依照上述方法,我们找到一个近邻的集合,接下来就是计算所有的距离和对这些点进行排序,找到最近的k个点。
很明显,我们会丢掉一些最近的点,这也是为什么叫近似最近邻的原因。
Annoy在实际使用的时候,提供了一种机制可以调整(搜索k),你能够根据它来权衡性能(时间)和准确度(质量)。
tips:
1.距离计算,采用归一化的欧氏距离:vectors = sqrt(2-2*cos(u, v))
2.向量维度较小(<100),即使维度到达1000变现也不错
3.内存占用小
4.索引创建与查找分离(特别是一旦树已经创建,就不能添加更多项)
5.有两个参数可以用来调节Annoy 树的数量n_trees和搜索期间检查的节点数量search_k
n_trees在构建时提供,并影响构建时间和索引大小。 较大的值将给出更准确的结果,但更大的索引。
search_k在运行时提供,并影响搜索性能。 较大的值将给出更准确的结果,但将需要更长的时间返回。
如果不提供search_k,它将默认为n *
n_trees,其中n是近似最近邻的数目。
否则,search_k和n_tree大致是独立的,即如果search_k保持不变,n_tree的值不会影响搜索时间,反之亦然。
基本上,建议在可用负载量的情况下尽可能大地设置n_trees,并且考虑到查询的时间限制,建议将search_k设置为尽可能大。
近似最近邻算法-annoy解析的更多相关文章
- Annoy解析
Annoy是高维空间求近似最近邻的一个开源库. Annoy构建一棵二叉树,查询时间为O(logn). Annoy通过随机挑选两个点,并使用垂直于这个点的等距离超平面将集合划分为两部分. 如图所示,图中 ...
- JS-常考算法题解析
常考算法题解析 这一章节依托于上一章节的内容,毕竟了解了数据结构我们才能写出更好的算法. 对于大部分公司的面试来说,排序的内容已经足以应付了,由此为了更好的符合大众需求,排序的内容是最多的.当然如果你 ...
- 在opencv3中实现机器学习算法之:利用最近邻算法(knn)实现手写数字分类
手写数字digits分类,这可是深度学习算法的入门练习.而且还有专门的手写数字MINIST库.opencv提供了一张手写数字图片给我们,先来看看 这是一张密密麻麻的手写数字图:图片大小为1000*20 ...
- 使用C语言实现二维,三维绘图算法(2)-解析曲面的显示
使用C语言实现二维,三维绘图算法(2)-解析曲面的显示 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...
- KNN(k-nearest neighbor的缩写)又叫最近邻算法
KNN(k-nearest neighbor的缩写)又叫最近邻算法 机器学习笔记--KNN算法1 前言 Hello ,everyone. 我是小花.大四毕业,留在学校有点事情,就在这里和大家吹吹我们的 ...
- 【算法】K最近邻算法(K-NEAREST NEIGHBOURS,KNN)
K最近邻算法(k-nearest neighbours,KNN) 算法 对一个元素进行分类 查看它k个最近的邻居 在这些邻居中,哪个种类多,这个元素有更大概率是这个种类 使用 使用KNN来做两项基本工 ...
- 最近邻算法(KNN)
最近邻算法: 1.什么是最近邻是什么? kNN算法全程是k-最近邻算法(k-Nearest Neighbor) kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数数以一个类型别 ...
- Adaboost 算法实例解析
Adaboost 算法实例解析 1 Adaboost的原理 1.1 Adaboost基本介绍 AdaBoost,是英文"Adaptive Boosting"(自适应增强)的缩写,由 ...
- 2. Attention Is All You Need(Transformer)算法原理解析
1. 语言模型 2. Attention Is All You Need(Transformer)算法原理解析 3. ELMo算法原理解析 4. OpenAI GPT算法原理解析 5. BERT算法原 ...
随机推荐
- javascript_11-函数面试题
函数经典面试题 1.---------------------------- // 解析器: // 预解析 全局作用域 // 先找var .function 和参数 // 找到var和function ...
- 记录一下JProfiler的使用
刚入职实习,第四天了,昨晚老大安排我在公司机器上装个JProfiler看一情况. 然后网上都是什么跟tomcat一起使用的,所以折腾了很久才搞出来. 我这里没用什么服务器,因为公司用的是Play!框架 ...
- ubuntu 使用MySQL Workbench 连接远程云服务器mysql
前提:我的是腾讯云的服务器,所以需要在安全组开发端口. 配置安全组 1.创建新用户 一般为了安全性,我们不直接使用root用户,而是选择创建一个新用户. 在服务器中,输入 mysql -u root ...
- Linux命令——finger
简介 查询并显示系统用户的相关信息. 最小化安装Linux可能没有改名了,需要单独安装. RHEL/CentOS yum install finger* -y Ubuntu apt-get inst ...
- SOUL软件小结
soul 基于心灵的智能社交APP.功能是寻找最适合自己的灵魂伴侣 基于心灵测试给你智能匹配最简单的社交关系 匿名聊天软件一般都是没有机器人的,机器人一般不能对点聊很长时间 用户来源与动机 用户引流来 ...
- nn.Conv2d 参数及输入输出详解
Torch.nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=Tru ...
- 解密Redis持久化【翻译】
本文来自Redis的作者,他在论坛看到大家对Redis持久化误解较大,所以写此文章论述持久化 写操作的流程 首先我们来看一下数据库在进行写操作时到底做了哪些事,主要有下面五个过程. 客户端向服务端发送 ...
- 投掷硬币(概率dp)
小Hi有一枚神奇的硬币.已知第i次投掷这枚硬币时,正面向上的概率是Pi. 现在小Hi想知道如果总共投掷N次,其中恰好M次正面向上的概率是多少. Input 第一行包含两个整数N和M. 第二行包含N个实 ...
- Poj-3286- How many 0's? - 【基础数位DP】
How many 0's? Description A Benedict monk No.16 writes down the decimal representations of all natur ...
- WA又出现了
为甚么本蒟蒻写的代码永远有BUG? 为甚么本蒟蒻永远检查不出错误? 通过良久的分析,我得出一个结论:写代码也要有信仰. 人是要有信仰的,OI选手也不例外. 原因就是写之前没有膜拜上帝.真主.释迦摩尼. ...