kd树的原理
kd树就是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,可以运用在k近邻法中,实现快速k近邻搜索。构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分。
假设数据集\(T\)的大小是\(m*n\),即\(T={x_1,x_2,...x_m}\),其中\(x_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(n)})^T,i=1,2,...m\)。构建Kd树的过程大致如下。
对所有的数据,以\(x^{(1)}\)为轴,即取\(x_i^{(1)},i=1,2,...m\),并求得其中位数\(mid^{(1)}\),\(mid^{(1)}\)对应的点即为根节点,以\(mid^{(1)}\)为切分点,将剩余数据分为两个集合,左子树对应小于切分点的区域,右子树对应大于切分点的区域,然后针对每个集合,以\(x^{(2)}\)为轴,重复上述过程,继续切分为两个集合,然后不断重复上述过程,依次选择\(x^{(j)},j=1,2,...,n\)为轴,直到切分得到的集合中只有一个数据为止。
kd树的构造相对简单,那么如何利用kd树进行搜索?
给定一个目标点,搜索其最近邻,首先按照“左小右大”的规则,找到目标点所属区域对应的叶节点,然后从该叶节点出发,依次回退到父节点,不断查找与目标点最邻近的点,当确定不可能存在更近的节点时终止,这样搜索就被限制在空间的局部区域上,效率大大提高。
具体来说,
(1)从根节点出发,按照“左小右大”的规则,找到目标点所属区域对应的叶节点
(2)然后从该叶节点出发,向上回退,在回退到的每个父节点\(f\)上,执行一下两种操作:
(a)判断\(f\)与目标点的距离是否比当前最近距离更近,如果是,则将当前最近点更新为\(f\)
(b)当前最近点一定存在于\(f\)的一个子结点对应的区域中,即一定存在于\(f\)对应的区域中,即有可能\(f\)另一个 子结点距离目标点更近。判断目标点是否距离\(f\)另一个子结点对应区域更近,具体地,判断目标点与\(f\)对应的切 分轴 的距离是否小于当前最小距离,如果小于,从该子结点出发,重复执行步骤(2)
(3)当回退到根节点并完成对根节点步骤(2)中的两步操作时,搜索结束。当前最近点即为目标点的最近邻点。
以一个具体例子说明。如图1是生成的一颗kd树,特征空间划分如图2所示,要求目标点S(4.5,7.5)的最近邻点。


搜索过程如下:
(1)首先在kd树中找到了包含目标点S的叶节点D,D即为当前最近点,两点之间的距离是当前最近距离dist;
(2)向上回退到点B,点B距离点S更远,并且点B以\(x^{(2)}=5.5\)为切分轴,S距离\(x^{(2)}=5.5\)的距离大于dist,不用考虑点F;
(3)继续向上回退到根节点点A,点A距离点S更远,但是点A以\(x^{(1)}=5\)为切分轴,S距离\(x^{(1)}=5\)的距离小于dist,那么点S有可能距离A的右子树区域C中的点更近
(4)从点C出发,一直访问到点E,点E比点D距离点S更近,点E成为当前最近点,两点之间的距离是当前最近距离dist;
(5)从点E向上回退到点C,点C距离点S更远,并且点C以\(x^{(2)}=4.5\)为切分轴,S距离\(x^{(2)}=4.5\)的距离大于dist,不用考虑点G
(6)继续向上回退,再次回退到了根节点A,结束搜索,点E即为点S的最近邻点。
kd树的原理的更多相关文章
- kd树 求k近邻 python 代码
之前两篇随笔介绍了kd树的原理,并用python实现了kd树的构建和搜索,具体可以参考 kd树的原理 python kd树 搜索 代码 kd树常与knn算法联系在一起,knn算法通常要搜索k近邻, ...
- python kd树 搜索 代码
kd树就是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,可以运用在k近邻法中,实现快速k近邻搜索.构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,依次选择坐标轴对空间 ...
- 【特征匹配】SIFT原理之KD树+BBF算法解析
转载请注明出处:http://blog.csdn.net/luoshixian099/article/details/47606159 继上一篇中已经介绍了SIFT原理与C源代码剖析,最后得到了一系列 ...
- KD树——k=1时就是BST,里面的数学原理还是有不明白的地方,为啥方差划分?
Kd-Tree,即K-dimensional tree,是一棵二叉树,树中存储的是一些K维数据.在一个K维数据集合上构建一棵Kd-Tree代表了对该K维数据集合构成的K维空间的一个划分,即树中的每个结 ...
- kd树原理及实现
常用来作空间划分及近邻搜索,是二叉空间划分树的一个特例.通常,对于维度为k,数据点数为N的数据集,kd树适用于N≫2的k次方的情形. 1维数据的查询 假设在数据库的表格T中存储了学生的语文成绩chin ...
- 利用KD树进行异常检测
软件安全课程的一次实验,整理之后发出来共享. 什么是KD树 要说KD树,我们得先说一下什么是KNN算法. KNN是k-NearestNeighbor的简称,原理很简单:当你有一堆已经标注好的数据时,你 ...
- kd树和knn算法的c语言实现
基于kd树的knn的实现原理可以参考文末的链接,都是一些好文章. 这里参考了别人的代码.用c语言写的包括kd树的构建与查找k近邻的程序. code: #include<stdio.h> # ...
- PCL点云库:Kd树
Kd树按空间划分生成叶子节点,各个叶子节点里存放点数据,其可以按半径搜索或邻区搜索.PCL中的Kd tree的基础数据结构使用了FLANN以便可以快速的进行邻区搜索.FLANN is a librar ...
- KNN算法与Kd树
最近邻法和k-近邻法 下面图片中只有三种豆,有三个豆是未知的种类,如何判定他们的种类? 提供一种思路,即:未知的豆离哪种豆最近就认为未知豆和该豆是同一种类.由此,我们引出最近邻算法的定义:为了判定未知 ...
随机推荐
- 都能看懂的嵌入式linux/android alsa_aplay alsa_amixer命令行用法
前几天在嵌入式linux上用到alsa command,网上查的资料多不给力,只有动手一点点查,终于可以用了,将这个使用方法告诉大家,以免大家少走弯路. 0.先查看系统支持哪几个alsa cmd: l ...
- Socket 是嘛玩意儿(简单聊聊)
网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(API),对TCP/IP的封装 ...
- 如何退出minicom【学习笔记】
一.先按ctr+a进入设置模式 二.在按x退出
- Ubuntu 使用root登陆界面
打开终端开启root账户 :sudo passwd -u root 输入当前用户的密码 2.为root账户设置密码:sudo passwd root 设置root密码,输入两次 3.进入到/usr/s ...
- Numpy学习1
NumPy学习(1) 参考资料: http://www.cnblogs.com/zhanghaohong/p/4854858.html http://linusp.github.io/2016/02/ ...
- MCM写作
MCM 写作 引言的写作 对赛题的解读. 对现有研究成果的松树与评论 对解题思路和主要方法进行简介 引言第一句话是最重要的,应该激发读者阅读兴趣,应该浅显易懂,不用或者少用数学公式 赛题选定以后要首先 ...
- oracle 12c 报错 ora-03137 来自客户机的格式错误的TTC包被拒绝
昨天下午,实施报了一个oracle的报错ora-03137 说是数据库在11g时没有问题,升级到12c 时,就报错了. 本地调试,看到执行完sql后,报异常,如下: 把SqL在12c的数据库执行一下, ...
- 配置servlet支持文件上传
Servlet3.0为Servlet添加了multipart配置选项,并为HttpServletRequest添加了getPart和getParts方法获取上传文件.为了使Servlet支付文件上传需 ...
- ANDROID教程目录
html5 如何打包成apk,将H5封装成android应用APK文件的几种方法
- C++学习——C++复合类型
1.引用 引用是为某一个变量起了另一个名字,定义方式为type &rval = val; 引用类型必须与引用的变量类型完全一致,引用后,rval和val将会被视为一个变量,只不过有两种调用方式 ...