K近邻算法即是查找与当前点(向量)距离最近的K个点(向量),距离计算一般用欧氏距离。

最简单的方法就是穷举法:计算每个向量与当前向量的欧氏距离,选取最小的K个为所求。但这种方法计算量太大,无法应对大样本数的情况(比如SIFT特征点匹配,每张图片一般有几千个待匹配的特征点,对每个点都需要查找另一张图片中与之最相似的特征点从而建立对应关系,穷举法显然不行)。

SIFT采用的方法是:先将所有特征向量进行预处理,组成KD树的结构(二叉树),仅计算KD树中可能路径下(使用了BBF改进算法计算路径)特征向量的欧式距离,从而减小计算量。

本文将首先介绍KD树的构造,然后介绍KD树下的最近邻查找,最后介绍KD树下改进的查找方法BBF。

KD树的构造

KD树(k-dimension tree)是对数据点在K维空间中划分的一种数据结构

假设对于6个二维数据点(此时K=2):{(2,3), (5,4), (9,6), (4,7), (8,1), (7,2)}

(1)计算所有数据每一维的方差

在这里即计算(2, 5, 9, 6, 4, 7, 8)和(3, 4, 6, 7, 1, 2)的方差,分别为39和28.63

方差大的那一维(在这里为x轴)意味着当前数据在这一维分布最为分散,因此首先将数据按这一维进行划分

(2)选取方差最大的那一维中所有数据的中位数作为分割超面(根节点)

在这里选第一维(X轴)的数据,中位数为7,因此将x=7作为第一个分割超平面(点(7,2)作为根节点)

取中位数的好处是,能尽量保证左右子树的节点数平衡

(3)确定左子树右子树

经过(2)后,按x=7可将数据分成左子树:{(2,3), (5,4), (4,7)}和右子树:{(9,6), (8,1)}

然后分别对左右子树从(1)开始做递归,直到叶子节点

图1-1. KD树(左)和空间划分图(右)(截自《图像局部不变性特征与描述》)

注:考虑到计算方差增加的计算量,也有一种做法是:轮流选取维度进行划分(首先按第1维,KD树的第2层按第2维...)。显然这种方法分割得到的结果可区分度没有方差法好。

基于KD树的最近邻查找

还是以上一节的数据为例,假设待查找的数据是(2, 4.5)

(1)生成搜索路径

从根节点开始,按该层的分割面逐层向下搜索,直到叶节点

在这里首先比较(7,2),由于是按X轴划分,而2<7,因此搜索左节点(5,4), 该节点是按Y轴划分,而4.5>4,因此搜索右节点(4,7)。由于(4,7)已是 叶节点,搜索结束,得到搜索路径 (7,2)->(5,4)->(4,7)

记(4,7)为当前最近邻,计算两点的欧式距离3.2,为最近距离

(2)回溯

显然按(1)并不一定能得到全局最近邻,因此需要按路径回溯查找

首先判断当前点另一兄弟节点是否需要访问(KD树就是通过这种方式节省匹配时间的):如果已访问过或者当前点与该层分割面的距离大于当前最近距离,则放弃访问其兄弟分支,回溯至其父节点。

在这里(2,4.5) 与y=4的距离为0.5,小于3.2,因此需要搜索其左兄弟节点(2,3),计算(2,4.5)与(2,3)的距离1.5<3.2,因此更新最近邻为(2,3),最近距离为1.5;然后回溯至(5,4),由于(2,4.5)与x=7的距离为5,大于1.5,因此其右兄弟分支(9,6)不再搜索,最后回溯至(7,2),结束。该过程一共比较了4次。

图1-2. 以当前点为圆心,最近距离为半径画超圆,如果与分割超平面相交则搜索兄弟分支

KD树BBF快速搜索算法

KD树最近邻查找算法在回溯过程中通过计算超圆与超平面的距离决定是否比较兄弟分支,这在维数较低的时候能有效减小计算量;但当维数较高时(比如SIFT有128维)由于需要比较的分支太多,到最后基本上每个数据点都做了比较(与穷举法一样了),加上构建KD树的时间,此时算法性能甚至不如穷举法。

对K维的N个数据(节点),KD树最近邻查找算法的时间复杂度为,一般只有在数据规模和维度满足时才能保证该算法的高效。

Lowe等人(没错,提出SIFT的那伙人)提出的BBF(Best Bin First)方法,建立了一个优先序列,每次在优先序列里比较,通过限定最大比较次数/超时(我认为这是算法提速的核心),达到提高搜索效率的目的。该算法得到的解不一定是最优解,属于牺牲精度换效率的思路

(1)首先从根节点开始,按上节方式生成搜索路径,同时计算路径下每个节点与(2,4.5)的距离,将该节点的兄弟节点压入优先序列

搜索路径:(7,2)->(5,4)->(4,7),优先序列:{(2,3), (9,6)},最近点(5,4)

(2)提取优先序列中优先级最高的点(2,3),以该点为“根节点”,重复(1)

可以看到,BBF实现了按可能性排序的查询方式,然后通过限定次数来截断搜索(否则又与原始算法一样了),达到了快速检索的目的。

代码

https://github.com/sdeming/kdtree实现了基本的KD树及搜索,需要注意的是,其KD树的分割是按照维度轮流的方式实现的。

Rob Hess实现的SIFT算法中实现了BBF版的KD树算法

参考

[1] 《图像局部不变性特征与描述》

[2] Kd Tree算法原理和开源实现代码

K近邻快速算法 -- KD树、BBF改进算法相关推荐

  1. K近邻算法和KD树详细介绍及其原理详解

    相关文章 K近邻算法和KD树详细介绍及其原理详解 朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解 决策树算法和CART决策树算法详细介绍及其原理详解 线性回归算法和逻辑斯谛回归算法详细介绍及其原理详 ...

  2. 统计学习笔记(3)——k近邻法与kd树

    在使用k近邻法进行分类时,对新的实例,根据其k个最近邻的训练实例的类别,通过多数表决的方式进行预测.由于k近邻模型的特征空间一般是n维实数向量,所以距离的计算通常采用的是欧式距离.关键的是k值的选取, ...

  3. 《统计学习方法》—— k近邻方法、kd树以及python3实现

    前言 k近邻方法的初衷很简单,就是找最近的k个数据,根据这些数据的标记,按照某种规则,给新的数据标记.这里,我们可以看到三个重点:k值,距离度量和决策规则. k值决定方法的复杂程度.考虑k很大,足以包 ...

  4. K近邻法之kd树及其Python实现

    作为机器学习中一种基本的分类方法,K近邻(KNN)法是一种相对简单的方法.其中一个理由是K近邻法不需要对训练集进行学习.然而,不需要对训练集进行学习,反过来也会造成对测试集进行判定时,计算与空间复杂度 ...

  5. 【特征匹配】SIFT原理之KD树+BBF算法解析

    转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/47606159 继上一篇中已经介绍了SIFT原理与C源码剖析,最后得到了一系列特 ...

  6. 用python手写KNN算法+kd树及其BBF优化(原理与实现)(下篇)

    用python手写KNN算法+kd树及其BBF优化(原理与实现)(下篇) 接上一篇用python手写KNN算法+kd树及其BBF优化(原理与实现)(上篇) 我们使用training2和test2两个数 ...

  7. k-d树+bbf算法的介绍与实现

    最近还是一直在研究SIFT算法,而SIFT特征点匹配是一个比较经典的问题,使用暴力匹配的话确实可以得到结果,但是运行速度较慢.我的计算机处理是i5的二代系列,匹配两张各检测有2000+个SIFT特征点 ...

  8. KNN—Kd树—BBF优化

    一.KD树基本解释 1.1.基础概念 为了优化KNN的计算,使用KD树解决通过距离函数在高维矢量之间进行相似性检索的问题,快速而准确地找到查询点的近邻. 索引结构中相似性查询: 范围查询:给定查询点和 ...

  9. K近邻(k-Nearest Neighbor,KNN)算法,一种基于实例的学习方法

    1. 基于实例的学习算法 0x1:数据挖掘的一些相关知识脉络 本文是一篇介绍K近邻数据挖掘算法的文章,而所谓数据挖掘,就是讨论如何在数据中寻找模式的一门学科. 其实人类的科学技术发展的历史,就一直伴随 ...

最新文章

  1. Docker网络解决方案-Flannel部署记录
  2. 绝了!这款工具让SpringBoot不再需要Controller、Service、DAO、Mapper!
  3. html页面创建二维数组,二维数组到HTML表?
  4. Java 洛谷 P1307 数字反转
  5. 用实例证明dll中new的内存不能在exe中释放
  6. ml回归_ML中的分类和回归是什么?
  7. 使用ucontext组件实现的coroutine代码分析
  8. 添加毛玻璃的两中方法
  9. Spring Boot 返回 XML 数据,一分钟搞定!
  10. python字典示例简单代码_python学习笔记:字典的使用示例详解
  11. Oracle常见操作和命令
  12. 第十一章 Hibernate的查询 HQL面向对象的查询语言
  13. vue基础知识点思维导图
  14. synchronized的实现原理用法详解
  15. 2022年7月深圳地区CPDA数据分析师认证
  16. cache数据库入门教程 数据库m语言常用函数和命令
  17. 什么是SpringDataJPA
  18. 【3D Max】3D max如何删除环境贴图
  19. 系统检测,是否引证:否
  20. 深度学习高手该怎样炼成?这位拿下阿里天池大赛冠军的中科院博士为你规划了一份专业成长路径

热门文章

  1. 时间片轮转法(c语言)
  2. mysql 主键 索引类型_MYSQL常见索引类型(主键索引/唯一索引/普通索引/组合索引)...
  3. 快速选择无序数列的中位数
  4. Qt Java 实现短信群发功能 从搭建环境到功能实现
  5. 机器学习|VC维的理解
  6. 华为WATCH Buds耳机左右耳耗电不一样是怎么回事?
  7. 成人学英语怎么学好呢?
  8. 严重: Web应用程序 [/XXX_war_exploded] 注册了JDBC驱动程序 [com.mysql.cj.jdbc.Driver],但在Web应用程序停止时无法注销它。
  9. 深度学习常用激活函数
  10. 西南名族大学计算机科学与技术学院,西南民族大学计算机科学与技术学院副院长雷开彬一行来我院调研...