当前位置: 首页 > news >正文

算法笔记:KD树

1 引入原因

  • K近邻算法需要在整个数据集中搜索和测试数据x最近的k个点,如果一一计算,然后再排序,开销过大
    • 引入KD树的作用就是对KNN搜索和排序的耗时进行改进

2 KD树

2.1 主体思路

  • 以空间换时间,利用训练样本集中的样本点,沿各维度依次对k维空间进行划分,建立二叉树
  • 利用分治思想提高算法搜索效率
  • 二分查找的算法复杂度是O(logN)O(logN),KD树的搜索效率与之接近(取决于所构造kd-tree是否接近平衡树)

  •  上图为为训练样本对空间的划分以及对应的kd树
  • 绿色实心五角星为测试样本,通过kd-tree的搜索算法,快速找到与其最近邻的3个训练样本点(空心五角星标注的点)

2.2 KD树的建立

2.2.1 以一个例子引入

  • 比如我有6个点:(2,3),(4,7),(5,4),(7,2),(8,1),(9,6)
  • 1) 数据有两个维度,分别计算x,y方向上数据的方差
    • x方向上的方差最大
    • ——>先沿着X轴方向进行split
    • 注:这一步也可以不要,因为KD树适用的问题大多是维度小于20的,所以按照维度顺序一个一个来也没有问题
  • 2)根据x轴方向的值2,5,9,4,8,7排序选出中位数为7
    • x≤7的和x >7的被分开了
  • 3) 被分开的左半区和右半区分别选出y轴方向的中位数(偶数选小的那个)
  • 4)左上方三个点再根据x轴分一刀(其他三个区域已经各只剩一个点了)
  • 最终得到的KD树

2.2.2 伪代码

def kd_tree_construct:input: x: 训练样本集dim: 当前节点的分割维度(子节点的分割维度=(dim+1)%样本的维度)output: node: 构造好的kd tree的根节点if 只有一个数据点:创建一个叶子结点node包含这一单一的点node.point = x[0]node.son1 = Nonenode.son2 = Nonereturn nodeelse:记dim维度上的中位点为x(对x中的数据按dim维排序,取中位点,偶数个则取较小的那个)记xl为左集合(dim维小于p点的所有点)记xr为右集合(dim维大于p点的所有点)创建带有两个孩子的node:node.point = pnode.son1  = fit_kd_tree(xl)node.son2  = fit_kd_tree(xr)return node

2.3 KD树上的最近邻查找

2.3.1 伪代码

def kd_tree_search:global:Q, 缓存k个最近邻点(初始时包含一个无穷远点)q, 与Q对应,保存Q中各点与测试点的距离input: k, 寻找k个最近邻t, 测试点node, 当前节点(一开始时根节点)dim, 当前节点的分割维度(子节点的分割维度=(dim+1)%数据点的维度)output: 无if distance(t, node.point) < max(q):将node.point添加到Q,并同步更新q若Q内超过k个近邻点,则移出与测试点距离最远的那个点,并同步更新qif t[dim]-max(q) < node.point[dim]:kd_tree_search(k,t,node.son1)if t[dim]+max(q) > node.point[dim]:kd_tree_search(k,t,node.son2)

2.3.1 以一个例子开始

2.3.1.1 例子1 

搜索(2.1,3.1)

记k=1

  • 第1步:将(7,2)加入Q中,maxq=5.02,更新Q
    • 2.1-5.02≤7
      • 搜索左儿子
      • 第2步:将(5.4)加入Q中,maxq=3.04,更新Q
        • 3.1-3.04≤4
          • 搜索下儿子
          • 第3步:将(2,3)加入Q中,maxq=0.1414,更新Q
            • 已经是叶子节点了,结束
        • 3.1-3.04≥4
          • 搜索上儿子
          • 第4步:将(4,7)加入Q中,maxq=4.338>0.1414,不更新Q,仍为0.1414
            • 已经是叶子节点了,结束
    • 2.1-5.02≥7
      • 搜索右儿子
      • 第5步,将(9,6)加入Q中,maxq=7.484>0.1414,不更新Q,仍为0.1414
      • 3.1+7.484>6
        • 搜索上儿子
        • 没有上儿子,结束
  • 算法结束,最近的点是(2,3),q=0.1414

2.3.1.2 例子2 回溯时改变最近邻点

假设我们要查询的点是2,4.5

同样记k=1

  • 第1步:将(7,2)加入Q中,maxq=5.59,更新Q
    • 2-5.59≤7
      • 搜索左儿子
      • 第2步:将(5.4)加入Q中,maxq=3.04,更新Q
        • 4.5-3.04≤4
          • 搜索下儿子
          • 第3步:将(2,3)加入Q中,maxq=1.5,更新Q
        • 4.5+3.04≥4
          • 搜索上儿子
          • 第4步:将(4,7)加入Q中,maxq=3.20>1.5,不更新Q,仍为1.5
    • 2+5.59 >7
      • 搜索右儿子
      • 第5步,将(9,6)加入Q中,maxq=7.16>1.5,不更新Q,仍为1.5
        • 4.5+7.16>6
          • 搜索上儿子
          • 没有上儿子,结束
  • 算法结束,最近的点是(2,3),距离为1.5

参考内容:KNN的核心算法kd-tree和ball-tree - 简书 (jianshu.com)

k-d tree算法 - J_Outsider - 博客园 (cnblogs.com)

相关文章:

算法笔记:KD树

1 引入原因 K近邻算法需要在整个数据集中搜索和测试数据x最近的k个点&#xff0c;如果一一计算&#xff0c;然后再排序&#xff0c;开销过大 引入KD树的作用就是对KNN搜索和排序的耗时进行改进 2 KD树 2.1 主体思路 以空间换时间&#xff0c;利用训练样本集中的样本点&…...

plumelog介绍与应用-一个简单易用的java分布式日志系统

官方文档&#xff1a;http://www.plumelog.com/zh-cn/docs/FASTSTART.html 简介 无代码入侵的分布式日志系统&#xff0c;基于log4j、log4j2、logback搜集日志&#xff0c;设置链路ID&#xff0c;方便查询关联日志基于elasticsearch作为查询引擎高吞吐&#xff0c;查询效率高全…...

百度网盘删除“我的应用数据”文件夹

百度网盘删除“我的应用数据”文件夹电脑端方法-2023.2.27成功 - 哔哩哔哩 (bilibili.com) 百度网盘怎样删除我的应用数据文件夹-手机端方法-2023.3.24日成功 - 哔哩哔哩 (bilibili.com)...

多店铺智能客服,助力店铺销量倍增

近年来电商发展得非常快速&#xff0c;市场竞争也是愈发激烈了。商家不仅需要提高产品和服务的质量&#xff0c;还要争取为自己获取更多的曝光&#xff0c;以此来分散运营的风险和降低经营的成本&#xff0c;所以越来越多的商家也开始转向多平台多店铺运营。但即使运营多个平台…...

会话跟踪技术

cookie 是通过在浏览器第一次请求服务器时&#xff0c;在响应中放入cookie&#xff0c;浏览器接收到cookie后保存在本地&#xff0c;之后每次请求服务器时都将cookie携带到请求头中&#xff0c;用来验证用户身份与状态等。 缺点&#xff1a; 移动端app没有cookiecookie保存在…...

递归算法学习——子集

目录 一&#xff0c;题目解析 二&#xff0c;例子 三&#xff0c;题目接口 四&#xff0c;解题思路以及代码 1.完全深度搜索 2.广度搜索加上深度优先搜索 五&#xff0c;相似题 1.题目 2.题目接口 3.解题代码 一&#xff0c;题目解析 给你一个整数数组 nums &#xff0c…...

学习笔记:ROS使用经验(ROS报错)

报错&#xff1a;进程崩溃 ] process has died [pid 734, exit code -5, cmd /root/catkin_ws/devel/lib/pose_graph/pose_graph __name:pose_graph __log:/root/.ros/log/31b0ae1c-3295-11ee-bda9-02429b5737dc/pose_graph-5.log]. log file: /root/.ros/log/31b0ae1c-3295-11…...

设计模式二十四:访问者模式(Visitor Pattern)

用于将数据结构与数据操作分离&#xff0c;使得可以在不修改数据结构的情况下&#xff0c;定义新的操作。访问者模式的核心思想是&#xff0c;将数据结构和操作进行解耦&#xff0c;从而使得新增操作时不必修改数据结构&#xff0c;只需添加新的访问者。主要目的是在不改变数据…...

使用gn+Ninja构建项目

使用下载编译好的gn和ninja报错 先下载了gn的源码[gn.googlesource.com/gn]&#xff0c;然后编译报错&#xff0c;就直接下载了了编译号的gn和Ninja&#xff0c;然后写了Helloworld应用的BUILD.gn&#xff0c;然后将"gn\examples\simple_build\build"拷贝至当前目录…...

VMware虚拟机连不上网络

固定ip地址 进入网络配置文件 cd /etc/sysconfig/network-scripts 打开文件 vi ifcfg-ens33 编辑 BOOTPROTO设置为static&#xff0c;有3个值&#xff08;decp、none、static&#xff09; BOOTPROTO"static" 打开网络 ONBOOT"yes" 固定ip IPADDR1…...

安防视频监控/视频集中存储/云存储平台EasyCVR平台无法取消共享通道该如何解决?

视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等&#xff0c;视频智能分析平台EasyCVR融合性强、开放度…...

算法通关村-----如何基于数组和链表实现栈

实现栈的基本方法 push(T t)元素入栈 T pop() 元素出栈 Tpeek() 查看栈顶元素 boolean isEmpty() 栈是否为空 基于数组实现栈 import java.util.Arrays;public class ArrayStack<T> {private Object[] stack;private int top;public ArrayStack() {this.stack new…...

day-05 TCP半关闭 ----- DNS ----- 套接字的选项

一、优雅的断开套接字连接 之前套接字的断开都是单方面的。 &#xff08;一&#xff09;基于TCP的半关闭 Linux的close函数和windows的closesocket函数意味着完全断开连接。完全断开不仅不能发送数据&#xff0c;从而也不能接收数据。在某些情况下&#xff0c;通信双方的某一方…...

区块链金融项目怎么做?

区块链技术的兴起引发了金融领域的变革&#xff0c;为金融行业带来了前所未有的机遇与挑战。在这个快速发展的领域中&#xff0c;如何在区块链金融领域做出卓越的表现&#xff1f;本文将从专业性和思考深度两个方面&#xff0c;探讨区块链金融的发展路径&#xff0c;并为读者提…...

Redis与数据库保持一致

参考链接 先更新数据库&#xff0c;再更新redis 存在漏洞&#xff0c;如果更新Redis失败&#xff0c;仍然会导致不一致 先删Redis&#xff0c;再更新数据库并同步数据到Redis 存在漏洞&#xff0c;多线程情况下,线程1删除redis后&#xff0c;还是有可能被其他线程读取旧的数据…...

idea中vue项目 npm安装插件后node modules中找不到

从硬盘中重新加载一下...

已知两地经纬度,计算两地直线距离

文章目录 1 原理公式2 代码实现2.1 JavaScript2.2 C2.3 Python2.4 MATLAB 1 原理公式 在地球上&#xff0c;计算两点之间的直线距离通常使用地理坐标系&#xff08;例如WGS84&#xff09;。计算两地直线距离的公式是根据经纬度之间的大圆距离&#xff08;Great Circle Distanc…...

我想开通期权?如何开通期权账户?

场内期权的合约由交易所统一标准化定制&#xff0c;大家面对的同一个合约对应的价格都是一致的&#xff0c;比较公开透明&#xff0c;期权开户当天不能交易的&#xff0c;期权开户需要满足20日日均50万及半年交易经验即可操作&#xff0c;下文科普我想开通期权&#xff1f;如何…...

ChatGPT对软件测试的影响

ChatGPT 是一个经过预训练的 AI 语言模型&#xff0c;可以通过聊天的方式回答问题&#xff0c;或者与人闲聊。它能处理的是文本类的信息&#xff0c;输出也只能是文字。它从我们输入的信息中获取上下文&#xff0c;结合它被训练的大模型&#xff0c;进行分析总结&#xff0c;给…...

minion在ubuntu上的搭建步骤

在Ubuntu上搭建MinIO可以按照以下步骤进行&#xff1a; 下载MinIO服务器二进制文件&#xff1a; 通过浏览器访问 https://min.io/download 或使用以下命令获取最新的MinIO二进制文件&#xff1a;wget https://dl.min.io/server/minio/release/linux-amd64/minio赋予二进制文件…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

push [特殊字符] present

push &#x1f19a; present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中&#xff0c;push 和 present 是两种不同的视图控制器切换方式&#xff0c;它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...

[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.

ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #&#xff1a…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing

Muffin 论文 现有方法 CRADLE 和 LEMON&#xff0c;依赖模型推理阶段输出进行差分测试&#xff0c;但在训练阶段是不可行的&#xff0c;因为训练阶段直到最后才有固定输出&#xff0c;中间过程是不断变化的。API 库覆盖低&#xff0c;因为各个 API 都是在各种具体场景下使用。…...