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

本文介绍了K近邻法(KNN)的基本思想和在大数据集上计算复杂度高的问题,提出了kd树作为解决方案。kd树是一种二叉树结构,用于高效地在高维空间中寻找最近邻。文章详细解释了kd树的构建过程,并以一个二维数据集为例展示了kd树的构建。接着,文章阐述了如何利用kd树进行k近邻搜索的算法,并给出了Python实现kd树及其搜索的思路。尽管kd树在空间和时间复杂度上有所优化,但当数据量极大时,递归深度和空间复杂度仍是个挑战。
摘要由CSDN通过智能技术生成

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

K近邻法最简单的实现方法是对需要分类的目标点,计算出训练集中每一个点到其的距离(比较常用的有欧氏距离),然后选取K个距离目标最近的点,根据这些点的分类以多数表决的形式来决定目标点的分类。理论上该方法的时间复杂度为O(n)。当n的数量巨大时,时间开销是巨大的。

kd树是一种为了提高KNN方法效率的特殊数据结构,它的本质是二叉树,每一个节点代表着对k维输入空间上的某一位进行划分的超平面。构造kd树相当于不断使用垂直于坐标轴的超平面将K维空间划分。

构建树的过程中,依次按顺序选择k维空间的某一个特征,在该特征的坐标轴上通过某个实例的特征值确定超平面,该超平面垂直于选择的坐标轴,将当前的超矩形区域划分为左右两个子区域,此时输入实例以选择的特征上选择的点为界,被分在左右两个超矩形区域中。重复以上过程直到子区域没有实例为止。

下面以一个例子来说明kd树的构建过程(例子来自《统计学习方法》-李航):
给定一个二维空间的数据集 T = {(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}

首先选取k维空间的某一特征(该例为第一个,理论上先选择哪一个都是可行的,顺序应该也是任意的,为了简化描述过程,先选择第一个特征)。

所有数据集的第一个特征为{2, 5, 9,4, 8, 7},然后选取某个特征值来确定超平面。一般情况下选取中点(事实证明选取中点并不是在任何情况下都是最佳的,通过中点构建出的kd树在搜素时未必效率最高,例如在训练集中两个类别之间的相对距离较远,且某一类的数量远大于另一类的数量)(偶数个的情况下可以选靠后的点)。该例中中点值为7.以平面x(1) = 7为超平面,将空间分为左右两部分(左空间小于中点值,右空间大于中点值),左空间点(2,3)(4,7)(5,4),再以第二个特征值画超平面,此时第二个特征值的中点为4,以x(2)= 4为超平面再次划分左半平面,以此类推。最终得到的划分如下。

kd树如下

kd树构建完毕后,利用kd树进行k近邻搜索。在kd树上进行近邻搜索时,很多时候可以不进入某个父节点的另一个子节点(省去了另一个子节点数据点的查找)。kd树查找的具体算法如下:

算法输入:构造完毕的kd树,需要分类的目标点x

算法输出:目标点x的k近邻点

算法过程:

1通过深度优先方法,在kd树中搜索到目标点的所在的叶节点。(注:该搜索并不能直接找到最近邻点)搜索方法如下,在搜索每一层的过程中,根据该层的分割特征的序数,来对目标点的该序数的特征进行分类(决定是进入左子节点还是右子节点)。如目标点为(6,1),在根节点,分割特征为x(1),目标点的x(1)为 6,6小于根节点的x(1)= 7,进入左子节点。第二层的分割特征为x(2),目标点的x(2)为1, 1小于子节点的x(2)= 4,进入左子节点,最终得到叶节点(2,3)。

2 以该叶节点作为当前的NN(最近邻)点,计算该叶节点与目标点的距离,并设为当前的最小距离。

3 计算该叶节点父节点与目标点的距离,若小于当前的最小距离,则更新当前的最小距离以及当前的NN点(被覆盖的点先记录下来)

4 判断是否要进入父节点的另一个子节点:

判断方法为:计算父节点在其分割特征上的值距离目标点在该特征上的值的距离,若该距离小于当前的最小距离,则进入

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值