KNN算法进阶思路之KD树划分

本文探讨了在实现KNN算法时遇到的主要问题,即如何快速找到与查询点最近的k个样本。作者介绍了线性扫描方法,其缺点是耗时,然后引入了KD树,一种用于多维空间搜索的数据结构,通过构造和划分二维空间来提高搜索效率。后续会进一步讲解KD树的搜索方法和代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

主要问题:

当实现KNN算法的时候,主要问题是如何快速的,在训练样本中找到,距离我们要判断类型的样本点(以下简称点),最近的k个点。

解决方法:

1:线性扫描:

什么是线性扫描?线性扫描就是当你输入一个点的时候,就要计算这个点和所有已知类比的点的距离,然后通过比较(一般都是直接排序),然后找到最近的k个点。

我的上一篇博客中使用的方法就是这种,详情请点击关于KNN算法的基础及其底层代码实现

这种方法的缺点很明显:过于耗时!

2:KD树:

什么是KD树:

下面是百科给的解释:

很抽象,下面是我的理解:

KD树用于多维空间关键数据的搜索,这多维空间是什么意思呢?跟我们学的有什么联系呢?

上一篇博客中我已经说过,我们在分类问题中,是要对样本进行特征提取的,我们最终会提取成特征向量的形式,例如:某电影(戏剧内容,格斗内容,爱情内容......)在代码中就是(X1,X2,X3......)这就是一个特征向量。

而对于KD树算法,则是将特征向量看成多维空间内的一个点,其各个特征就是其在空间内对应各轴的坐标,就例如一只狗(眼睛颜色黄,毛发黄),我么们既定黄=21,则这只狗的特征向量就是(21,21),那么该样本所对应的点就在二维空间内。

KD树也是二叉树,二叉树相信大家都有所了解,KD树表示的是对k维空间的划分。

为什么要这样做呢,以下是我的理解:

(该图片来源于网络,侵权必删!)

如上图所示:我们给定一堆已有的样本数据,和一个被询问的数据点(红色五角星),我们如何找到离五角星最近的20个点?

直接算每个点跟五角星的距离肯定不现实,也不是我们的常用思路,一般我们都是找到能把五角星附近的一些点都给圈主,然后找离其最近的20个点,如下图所示:(该图片来源于网络,侵权必删!)

这画的这个圈圈其实就是对该二维空间的划分。

这下应该会有个大概了解了吧。

那么我们该如何划分?

算法步骤:

KD树算法包括以下三个步骤:

第一:构造KD树(划分)

第二:搜索最近邻

第三:预测

由于比较抽象,我们接下来就举例说明。

KD树的构造过程就是划分过程,上面就是我们要划分的目标,都是二维数据点(两个特征的样本点),所对应的空间也是二维空间。

划分的时候有两个注意点:

第一点:划分的维度,要根据数据点在各维度上的分布情况进行划分,方差越大,分布越离散,我们应当从方差大的维度开始划分,这样有更好的效果和平衡性。

补充:方差公式:

第二点:中值点的确定,一般都是先把所有点在所有维度上都进行依次排序,然后保存下来,这样后面就会方便很多。

现在我们开始构造:

KD树的构造(划分):

我们的示例:

因为是二维数据点,所在二维空间,那么接下来划分会方便一些

为了好显示,我先把划分的结果放在了这里。

在x轴上进行的排序:

(2,3)(4,5)(5,7)(6,4)(7,2)(9,6)

在y轴上的排序:

(7,2)(2,3)(6,4)(4,5)(9,6)(5,7)

第一次划分:

从x轴开始划分,我们先将他们沿着x轴方向对应的数进行排序,我们得到中位数6,我们过(6,4)点做垂直x轴的直线(其实这么说不太严谨,可是这是二维空间是一个平面,所以我就这么说了),进行一次划分,我们将它作为二叉树的根节点标记为0

这一步划分将剩下的点分成了两部分,即(2,3)(4,5)(5,7)左边一部分,(9,6)(7,2)右边一部分.

第二次划分:

这两个部分同时开始划分,两部分都沿着y轴上的数进行排序,左部份的到中值5,右部分的到中值6,那么过(4,5)点做y轴的垂线,其为(6,4)的左子节点,过(9,6)点做y轴的垂线,其为右子节点。,这样的话就相当于将二维空间划分成了四部分。

第三次划分:

四个部分同时划分,剩下的点沿着x轴上的数进行排序,其余同理......

第五次划分:

同理

这个划分沿着的某某轴,都是循环的,一般而言,二维空间就是X->Y->X->Y->......

三维就是:X->Y->Z->X->......

多维X->Y->Z->......->X->Y->Z->......->X->Y->Z......

当然我们上面也说了,要看各个轴方向对应的数所显示的离散程度。

最后就会得到这样的二叉树及其图像:

这D ,D1,D2什么的不用管就是标号而已,0,1,2,3则是做的记号,下面的图是按照记号与之对应的:

这下的话,应该可以明白二叉树怎么划分的基本方法了。

后面将介绍,KD树的搜索找最近邻,还有代码实现以及KNN算法的快速代码使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值