KD树
实现k近邻算法时,主要考虑的问题是如何对训练数据进行快速k近邻搜索。

这在特征空间的维数大及训练数据容量大时尤其必要。

k近邻法最简单的实现是线性扫描(穷举搜索),即要计算输入实例与每一个训练实例的距离。计算并存储好以后,再查找K近邻。当训练集很大时,计算非常耗时。

为了提高kNN搜索的效率,可以考虑使用特殊的结构存储训练数据,以减小计算距离的次数。

k值选择问题。1

kd树

如果A和B距离很远,B和C距离很近,那么A和C的距离也很远。

原理

![在这里插入图片描述](https://img-blog.csdnimg.cn/20201106093602311.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODg3MTk4OA==,size_16,color_FFFFFF,t_70#pic_center
构造方法
(1)构造根结点,使根结点对应于K维空间中包含所有实例点的超矩形区域;

(2)通过递归的方法,不断地对k维空间进行切分,生成子结点

(3)上述过程直到子区域内没有实例时终止(终止时的结点为叶结点)。

。。。

最近邻域搜索(Nearest-Neighbor Lookup)

kd树(K-dimension tree)是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。kd树是一种二叉树,表示对k维空间的一个划分,构造kd树相当于不断地用垂直于坐标轴的超平面将K维空间切分,构成一系列的K维超矩形区域。kd树的每个结点对应于一个k维超矩形区域。利用kd树可以省去对大部分数据点的搜索,从而减少搜索的计算量。

类比“二分查找”:给出一组数据:[9 1 4 7 2 5 0 3 8],要查找8。如果挨个查找(线性扫描),那么将会把数据集都遍历一遍。而如果排一下序那数据集就变成了:[0 1 2 3 4 5 6 7 8 9],按前一种方式我们进行了很多没有必要的查找,现在如果我们以5为分界点,那么数据集就被划分为了左右两个“簇” [0 1 2 3 4]和[6 7 8 9]。

因此,根本就没有必要进入第一个簇,可以直接进入第二个簇进行查找。把二分查找中的数据点换成k维数据点,这样的划分就变成了用超平面对k维空间的划分。空间划分就是对数据点进行分类,“挨得近”的数据点就在一个空间里面。

构造方法
(1)构造根结点,使根结点对应于K维空间中包含所有实例点的超矩形区域;

(2)通过递归的方法,不断地对k维空间进行切分,生成子结点。在超矩形区域上选择一个坐标轴和在此坐标轴上的一个切分点,确定一个超平面,这个超平面通过选定的切分点并垂直于选定的坐标轴,将当前超矩形区域切分为左右两个子区域(子结点);这时,实例被分到两个子区域。

(3)上述过程直到子区域内没有实例时终止(终止时的结点为叶结点)。在此过程中,将实例保存在相应的结点上。

(4)通常,循环的选择坐标轴对空间切分,选择训练实例点在坐标轴上的中位数为切分点,这样得到的kd树是平衡的(平衡二叉树:它是一棵空树,或其左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是平衡二叉树)。

KD树中每个节点是一个向量,和二叉树按照数的大小划分不同的是,KD树每层需要选定向量中的某一维,然后根据这一维按左小右大的方式划分数据。在构建KD树时,关键需要解决2个问题:

(1)选择向量的哪一维进行划分;

(2)如何划分数据;

第一个问题简单的解决方法可以是随机选择某一维或按顺序选择,但是更好的方法应该是在数据比较分散的那一维进行划分(分散的程度可以根据方差来衡量)。

第二个问题中,好的划分方法可以使构建的树比较平衡,可以每次选择中位数来进行划分。

案例分析
树的建立
给定一个二维空间数据集:T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},构造一个平衡kd树。

第一维度方差交大,分散程度大
选接近中位数的节点
x轴比较分散,所以选择x轴开始划分
选择X的中位数最近的5或者7,这里选择7

第一步x轴划分(紫色)
第二部y轴左划分(黄色)
第三步y轴右划分(黑色)


思路引导:

根结点对应包含数据集T的矩形,选择x(1)轴,6个数据点的x(1)坐标中位数是6,这里选最接近的(7,2)点,以平面x(1)=7将空间分为左、右两个子矩形(子结点);接着左矩形以x(2)=4分为两个子矩形(左矩形中{(2,3),(5,4),(4,7)}点的x(2)坐标中位数正好为4),右矩形以x(2)=6分为两个子矩形,如此递归,最后得到如下图所示的特征空间划分和kd树。

最近领域的搜索
举例:查找点(2.1,3.1)

在(7,2)点测试到达(5,4),在(5,4)点测试到达(2,3),然后search_path中的结点为<(7,2),(5,4), (2,3)>,从search_path中取出(2,3)作为当前最佳结点nearest, dist为0.141;

然后回溯至(5,4),以(2.1,3.1)为圆心,以dist=0.141为半径画一个圆,并不和超平面y=4相交,如上图,所以不必跳到结点(5,4)的右子空间去搜索,因为右子空间中不可能有更近样本点了。

于是再回溯至(7,2),同理,以(2.1,3.1)为圆心,以dist=0.141为半径画一个圆并不和超平面x=7相交,所以也不用跳到结点(7,2)的右子空间去搜索。

至此,search_path为空,结束整个搜索,返回nearest(2,3)作为(2.1,3.1)的最近邻点,最近距离为0.141。
回溯:
放入栈中依次往出来取比较距离
半径超过,把点重新放入栈中,依次取出比较

查找点(2,4.5)

在(7,2)处测试到达(5,4),在(5,4)处测试到达(4,7)【优先选择在本域搜索】,然后search_path中的结点为<(7,2),(5,4), (4,7)>,从search_path中取出(4,7)作为当前最佳结点nearest, dist为3.202;

然后回溯至(5,4),以(2,4.5)为圆心,以dist=3.202为半径画一个圆与超平面y=4相交,所以需要跳到(5,4)的左子空间去搜索。所以要将(2,3)加入到search_path中,现在search_path中的结点为<(7,2),(2, 3)>;另外,(5,4)与(2,4.5)的距离为3.04 < dist = 3.202,所以将(5,4)赋给nearest,并且dist=3.04。

回溯至(2,3),(2,3)是叶子节点,直接平判断(2,3)是否离(2,4.5)更近,计算得到距离为1.5,所以nearest更新为(2,3),dist更新为(1.5)

回溯至(7,2),同理,以(2,4.5)为圆心,以dist=1.5为半径画一个圆并不和超平面x=7相交, 所以不用跳到结点(7,2)的右子空间去搜索。

至此,search_path为空,结束整个搜索,返回nearest(2,3)作为(2,4.5)的最近邻点,最近距离为1.5。


总结:
kd树的构建过程
1.构造根节点
2.通过递归的方法,不断地对k维空间进行切分,生成子节点
3.重复第二步骤,直到子区域中没有示例时终止
需要关注细节:a.选择向量的哪一维进行划分;b.如何划分数据

kd树的搜索过程
1.二叉树搜索比较待查询节点和分裂节点的分裂维的值,(小于等于就进入左子树分支,大于就进入右子树分支直到叶子结点)
2.顺着“搜索路径”找到最近邻的近似点
3.回溯搜索路径,并判断搜索路径上的结点的其他子结点空间中是否可能有距离查询点更近的数据点,如果有可能,则需要跳到其他子结点空间中去搜索
4.重复这个过程直到搜索路径为空


  1. (注:)1) 选择较小的K值,就相当于用较小的领域中的训练实例进行预测,
    “学习”近似误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是“学习”的估计误差会增大,
    换句话说,K值的减小就意味着整体模型变得复杂,容易发生过拟合;2) 选择较大的K值,就相当于用较大领域中的训练实例进行预测,
    其优点是可以减少学习的估计误差,但缺点是学习的近似误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误。且K值的增大就意味着整体的模型变得简单。3) K=N(N为训练样本个数),则完全不足取,
    因为此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单,忽略了训练实例中大量有用信息。
    在实际应用中,K值一般取一个比较小的数值,例如采用交叉验证法(简单来说,就是把训练数据在分成两组:训练集和验证集)来选择最优的K值。 ↩︎

机器学习算法之二KD树相关推荐

  1. 半路算法之二项树与二项堆

    半路算法之二项树与二项堆 秉承前文.前面提到过针对稀疏图时,以二项堆来作为最小优先队列是更为适宜的.这里记录一下学习二项堆的过程. 二项堆的名字来源于二项树.二项堆是多个二项树连在了一起. 二项树的名 ...

  2. 机器学习算法(二):基于决策树的分类预测

    机器学习算法(二):基于决策树的分类预测 决策树的介绍和应用 简介 决策树构建的伪代码 特征划分选择 信息增益 信息增益率 基尼系数 应用场景 优缺点 基于企鹅数据集的决策树实战 Step1:函数库导 ...

  3. 机器学习算法(二十五):KD树详解及KD树最近邻算法

    目录 1 KD树 1.1 什么是KD树 1.2 KD树的构建 1.3 KD树的插入 1.4 KD树的删除 1.5 KD树的最近邻搜索算法 1.5.1 举例:查询点(2.1,3.1) 1.5.2 举例: ...

  4. python机器学习案例系列教程——K最近邻算法(KNN)、kd树

    全栈工程师开发手册 (作者:栾鹏) python数据挖掘系列教程 K最近邻简介 K最近邻属于一种估值或分类算法,他的解释很容易. 我们假设一个人的优秀成为设定为1.2.3.4.5.6.7.8.9.10 ...

  5. 统计学习方法笔记(二)-kd树原理及python实现

    kd树 kd树简介 构造平衡kd树算法原理 kd树代码实现 案例地址 kd树简介 kdkdkd树是一种对kkk维空间中的实例点进行存储以便对其进行快速检索的树形数据结构. kdkdkd树构造方法: 构 ...

  6. 机器学习算法(二十七):贝叶斯网络

    目录 1. 对概率图模型的理解 2. 贝叶斯方法 2.1 频率派观点 2.2 贝叶斯学派 2.3 贝叶斯定理 2.4 应用:拼写检查 3 贝叶斯网络 3.1 贝叶斯网络的定义 3.2 贝叶斯网络的3种 ...

  7. 机器学习----KNN中的Kd树及BBF优化

    一.KD树基本解释 1.1.基础概念 1.2.什么是KD树 1.3.KD树的构建 1.3.1.算法的实现 1.3.2.构造代码部分 1.3.2.具体步骤 二.KD树基本操作 2.1.KD树查找 2.2 ...

  8. java树的基本知识_Java数据结构和算法(二)树的基本操作

    Java数据结构和算法(二)树的基本操作 一.树的遍历 二叉树遍历分为:前序遍历.中序遍历.后序遍历.即父结点的访问顺序 1.1 前序遍历 基本思想:先访问根结点,再先序遍历左子树,最后再先序遍历右子 ...

  9. 机器学习 K近邻之KD树基本概念、绘制KD树

    K近邻算法回顾 K近邻法模型的三要素: 距离度量:  K值的选取:K值的选取一般可以采用交叉验证法,且一般小于训练集样本量的平方根 分类决策规则:多数表决等价于误分类数最小 关于K近邻的问题: 1.简 ...

最新文章

  1. 8086处理器的无条件转移指令——《x86汇编语言:从实模式到保护模式》读书笔记13
  2. python中的序列类型和序列号_python~序列类型及操作
  3. matlab sort三维_matlab练习题
  4. POJ 1007 DNA Sorting
  5. mysql常用sql总结_获取多个字段最大值最小值
  6. 装好XP,打开SATA开机蓝屏解决方法
  7. Humble Numbers(丑数) 超详解!
  8. cmd命令行开启windows远程桌面服务
  9. 如何成为一个合格的ASF贡献者?
  10. MEGA这个网盘你可以拥有,超级良心
  11. python如何循环sql语句_sql语句的for循环语句怎么写
  12. Oracle优化器详解,通宵整理,透彻超详细
  13. SaaS前世今生:老树开新花
  14. 创业商业计划PPT模板
  15. 重新启动计算机以关闭用户账户控制,win10如何彻底关闭用户帐户控制?
  16. Dracena:实时数字孪生平台
  17. CAS号:60535-02-6,二肽Met-Trp
  18. <video> 标签快进不生效
  19. 多传感器融合及其应用
  20. 高级刀片服务器系统,刀片服务器系统

热门文章

  1. MySQL主从不一致的修复过程(r10笔记第96天)
  2. 基于“业务中台”构建的一些理解
  3. Android 通用流行框架梳理
  4. 《Effective Modern C++》Item 6: Use the explicitly typed initializer idiom when auto deduces undesired
  5. npm run serve 报错:Error: error:0308010C:digital envelope routines::unsupported
  6. 安全进阶:虚拟防火墙基础实验
  7. 关于Mastering-OpenCV3第二版的代码跑通--关于PCL的一些问题
  8. 线段树模板(建树+更新)
  9. 机器学习四大数据降维方法详解
  10. python3.8与pyinstaller_pyinstaller 3.5 在python 3.8 环境下出现不兼容的问题