KNN中的优化算法KD-tree

article/2025/9/7 7:58:48


我们知道KNN是基于距离的一个简单分类算法,熟悉KNN的都知道,我们要不断计算两个样本点之间的距离,但是,试想一下,如果数据量特别大的时候,我们要每个都计算一下,那样计算量是非常大的,所以提出了一种优化KNN的算法-----kd-tree.


实现k近邻法时,主要考虑的问题是如何对训练数据进行快速k近邻搜索。这在特征空间的维数大及训练数据容量大时尤其必要。k近邻法最简单的实现是线性扫描(穷举搜索),即要计算输入实例与每一个训练实例的距离。计算并存储好以后,再查找K近邻。当训练集很大时,计算非常耗时。为了提高kNN搜索的效率,可以考虑使用特殊的结构存储训练数据,以减小计算距离的次数。


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


构造平衡kd树算法: 
输入: k维空间数据集 T={x1,x2,...,xN},其中 xi=(xi(1),xi(2),...,xi(k)),i=1,2,...,N;
输出:kd树

(1)开始:构造根结点,根结点对应于包含T的k维空间的超矩形区域。选择 x(1)为坐标轴,以T中所有实例的 x(1)坐标的中位数为切分点,将根结点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴 x(1)垂直的超平面实现。由根结点生成深度为1的左、右子结点:左子结点对应坐标 x(1)小于切分点的子区域,右子结点对应于坐标 x(1)大于切分点的子区域。将落在切分超平面上的实例点保存在根结点

(2)重复。对深度为j的结点,选择 x(l)为切分的坐标轴, l=j%k+1,以该结点的区域中所有实例的 x(l)坐标的中位数为切分点,将该结点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴 x(l)垂直的超平面实现。由该结点生成深度为j+1的左、右子结点:左子结点对应坐标 x(l)小于切分点的子区域,右子结点对应坐标 x(l)大于切分点的子区域。将落在切分超平面上的实例点保存在该结点


举个简单的例子:

下面用一个简单的2维平面上的例子来进行说明。

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

  解:根结点对应包含数据集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树。


这里注意一下:


从我们的数据集中可以看到,我们是二维的数据,x(1)是表示第一维的数据,x(2)是表示第二维的数据,在我们构造树求中位数的时候,我们先看低维的数据,也就是第一维的数据,即:x(1),在x(1)的基础上,先排序,然后再求中位数。然后再看根节点中位数左边和右边,这个时候注意啦,不是再看第一维了,而是看第二维了,也就是x(2),在x(2)的基础上,排序,求中位数。如果数据是3维,那么下一层就看第三维,。。以此反复类推下去。





kd树我们建立好了,那么我们现在需要来提高算法速度了。怎么做呢?


搜索kd树

  利用kd树可以省去对大部分数据点的搜索,从而减少搜索的计算量。下面以搜索最近邻点为例加以叙述:给定一个目标点,搜索其最近邻,首先找到包含目标点的叶节点;然后从该叶结点出发,依次回退到父结点;不断查找与目标点最近邻的结点,当确定不可能存在更近的结点时终止。这样搜索就被限制在空间的局部区域上,效率大为提高

  用kd树的最近邻搜索:  
输入: 已构造的kd树;目标点 x; 
输出: x的最近邻。

(1) 在kd树中找出包含目标点 x的叶结点:从根结点出发,递归的向下访问kd树。若目标点当前维的坐标值小于切分点的坐标值,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止

(2) 以此叶结点为“当前最近点”

(3) 递归的向上回退,在每个结点进行以下操作

  (a) 如果该结点保存的实例点比当前最近点距目标点更近,则以该实例点为“当前最近点”

  (b) 当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一个子结点对应的区域是否有更近的点。具体的,检查另一个子结点对应的区域是否与以目标点为球心、以目标点与“当前最近点”间的距离为半径的超球体相交。如果相交,可能在另一个子结点对应的区域内存在距离目标更近的点,移动到另一个子结点。接着,递归的进行最近邻搜索。如果不相交,向上回退

(4) 当回退到根结点时,搜索结束。最后的“当前最近点”即为 x的最近邻点



注意:这里的搜索,也是跟上边构造一样,首先先搜索x(1),再搜索x(2)..以此类推下去。


  以先前构建好的kd树为例,查找目标点(3,4.5)的最近邻点。同样先进行二叉查找,先从(7,2)查找到(5,4)节点,在进行查找时是由y = 4为分割超平面的,由于查找点为y值为4.5,因此进入右子空间查找到(4,7),形成搜索路径:(7,2)→(5,4)→(4,7),取(4,7)为当前最近邻点。以目标查找点为圆心,目标查找点到当前最近点的距离2.69为半径确定一个红色的圆。然后回溯到(5,4),计算其与查找点之间的距离为2.06,则该结点比当前最近点距目标点更近,以(5,4)为当前最近点。用同样的方法再次确定一个绿色的圆,可见该圆和y = 4超平面相交,所以需要进入(5,4)结点的另一个子空间进行查找。(2,3)结点与目标点距离为1.8,比当前最近点要更近,所以最近邻点更新为(2,3),最近距离更新为1.8,同样可以确定一个蓝色的圆。接着根据规则回退到根结点(7,2),蓝色圆与x=7的超平面不相交,因此不用进入(7,2)的右子空间进行查找。至此,搜索路径回溯完,返回最近邻点(2,3),最近距离1.8。




http://chatgpt.dhexx.cn/article/nfnhmYQ1.shtml

相关文章

KNN算法代码

一、K近邻算法 KNN是一种监督学习类别的算法,全称(K-NearestNeighbor)直译为K个最近的邻居,是一种聚类算法。该算法认为我们在判断一个物体的类别可以根据与他非常相似的K个物体的类别(这K个物体的类别是已知的&#x…

KNN数据缺失值填充(附源码和数据)不调用包

KNN估计 数据缺失值填充—KNN估计一、基本思想二、步骤1.导入数据2.查看空缺值3.取出要分析的数据4.计算平均值5.计算标准差6.规范化7.计算欧几里得距离8.最优解9.画图 总结 数据缺失值填充—KNN估计 运行环境 python3.6 jupyter notebook 一、基本思想 先将数据标准化&…

数据挖掘——KNN算法的实现

👨‍💻作者简介:练习时长两年半的java博主 📖个人主页:君临๑ 🎁 ps:点赞是免费的,却可以让写博客的作者开心好几天😎 文章目录 一、k-最近邻分类算法介绍 二、k-NN的特…

KNN算法调优

1.所用方法: 交叉验证与网格搜索 交叉验证(为了让被评估的模型更加精确可信): 所有训练集数据分成N等分,几等分就是几折交叉验证 网格搜索:调参数 K-近邻:超参数K 2.API: sklearn.model_selection.GridSearchCV: CV即cross validation…

计算机编程—必备基础知识点

目录: 1. 编程语言1.1 编程1.2 计算机语言1.3 编程语言1.4 翻译器1.5 编程语言和标记语言区别 2. 计算机基础2.1 计算机组成2.2 数据存储2.3 数据存储单位2.4 程序运行 1. 编程语言 1.1 编程 编程:就是让计算机为解决某个问题而使用某种程序设计语言编…

计算机概论--计算机基础知识快速入门

0.前言1.计算机:辅助人脑的好工具 1.1计算机硬件的五大单元1.2CPU的种类1.3接口设备1.4运作流程 2.个人计算机架构与接口设备 2.1CPU2.2内存2.3显卡2.4硬盘与存储设备2.5主板 3.软件程序执行 3.1机器程序与编译程序3.2操作系统 3.2.1操作系统内核3.2.2系统调用 3.3小…

0基础如何开始学习计算机知识?

一、计算机的基本操作 计算机中只有文件和文件夹 计算机中,只有两样东西,文件和文件夹。 文件夹:本身不存储数据内容。文件夹是用来组织和管理文件的。 文件: 所有的txt文本文档,音乐,视频,图…

【电脑讲解】电脑知识入门大全,超详细电脑基础知识讲解

这是一个新坑,希望大家喜欢 电脑的基础知识大全,你确定都知道? 一、软件系统 软件系统包括:操作系统、应用软件等。应用软件中电脑行业的管理软件,IT电脑行业的发展必备利器,电脑行业的erp软件。 二、硬件系统 硬件系…

计算机知识01:计算机基础知识入门

1. 计算机运行流程 如果不是很了解电脑运行流程的话,我们可以类比一下,假设电脑是一个人体,那么每个元件对应到哪个地方呢?可以这样思考: CPU脑袋:每个人会做的事情都不一样(微指令集的差异&a…

IP地址(IP Address)

IP Address在网络中,通信节点都需要一个IP地址 以点分十进制表示,有32位二进制构成(大约43亿) 分为两个部分:网络位和主机位 网络位:代表IP地址所属的网段 主机位:代表网点上的某个节点 由子…

IP地址构成 ,以及如何求“网络地址“以及“广播地址“

IP地址(英语:IP Address, 全称:Internet Protocol Address)又称互联网协议地址。当设备连接网络,设备将被分配一个IP地址,用作标识。通过IP地址,设备间可以互相通讯,如果没有IP地址&…

电话号码对应的英语单词

问题: 电话的号码盘一般可以用于输入字母,如用2可以输入a,b,c,用3可以输入d,e,f等。 对于号码5869872,可以依次输出其代表的所有字母组合。如:jtmwtpa,jtmwtpb......... 1、您能否可以根据这样的对应关系设计一个程序&#xff…

地址的概念

前言:地址的概念 1. 地址概念及各个单位换算1.1 地址的概念1.2 单位换算1.3 举例说明,加深理解1.4 关于地址的宽度 1. 地址概念及各个单位换算 1.1 地址的概念 计算机内的数据是存储在地址里面的,地址又是以字节(Byte&#xff09…

地址的地址?

在visual studio 2019中 #include <stdio.h> #include <stdlib.h> typedef struct student { int value; struct student* next_stu; }Student; Student * creatlist(); void insertlist(Student * list,int value); int main() { Student *my_list…

GoldenDict 上的那些精美版权词典(附下载地址)(英语、俄语、梵语、印地语)

转载▼ 标签&#xff1a; 杂谈 国内的有道词典和金山词典由于使用方便、宣传到位得到了许多同学的喜爱。在开源软件的领域&#xff0c;也有一款非常好用的词典GoldenDict&#xff0c;它的强项在于可以直接使用众多词典厂商的词库。那些正规的词典厂商通常购买了词典的版权…

【GO】map转json

咔咔博客之map转json 跟结构体转json一样都使用的是json.Marshal()方法 最后需要就是把字节转为字符串使用string即可 案例 func main() {// 定义了interface 后边就可以跟任意类型了mMap : make(map[string]interface{})mMap["博客地址"] "blog.fangkang.to…

Json4s的一些用法 JSon转对象实体 Json转Map Map转Json

Json4s 全称就是Json For Scala&#xff0c;为Scala而生 首先上Maven依赖配置&#xff0c;其实Spark中自带了Json4s如果是编写Spark代码,并不需要单独引用Json4s的依赖了 <dependency><groupId>org.json4s</groupId><artifactId>json4s-jackson_2.11&…

map转json字符串字段排序

需求&#xff1a;map转成json字符串&#xff0c;要求字段按字母升序排列 package com.data.test;import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.SerializerFe…

Map与JSON数据之间的互相转化

Map与JSON mapmap转JSON字符串JSON字符串转JSON对象Map转JSON对象JSON字符串转MapJSON对象转MapJSON对象转JSON字符串IDEA功能快捷键 map 此内容是方便博主自己记忆内容&#xff0c;不用于公开学习资料&#xff0c;若发现语法错误&#xff0c;自行更正&#xff0c;勿喷 map转…

Map和JSON之间的转化

Map和JSON之间的转化 1 添加依赖 <dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.47</version></dependency>2 测试 2.1 Map转JSON //1.map转jsonTestpublic void testJson01()…