使用matlab建立Kd-tree并进行k-NN查询

kd树简介 在matlab下VLFeat中的kd-tree使用 先简要介绍knn——K近邻算法和kd-tree——kd树,然后介绍matlab环境中有关使用kd树的函数。k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构。主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索)。 这里用的是在VLFeat 实现的kd树,其是一个开源的计算机视觉库,实现了 SIFT,MSER, k-means, hierarchical k-means, aggl 阅读详情

文章中关于搜索算法的实现部分貌似有些问题,后面有一篇文章重新写了一遍关于kd-tree的内容,欢迎参阅,这篇文章的错误目前没有修正。

使用matlab对输入数据建立Kd-tree并通过Kd-tree进行k-NN查询。
k-NN查询的主要算法思路来自【量化课堂】kd 树算法之详细篇

在这里插入图片描述

clear;
close all;
clc;
% 生成数据
data = [2 3;
    5 4;
    9 6;
    4 7;
    8 1;
    7 2];
% 给数据标号
for i = 1: size(data,1)
    data(i,3) = i;
end
% 建立Kd树
Kd_tree = Kd_tree_create(data);
% 利用Kd树进行kNN查询
closest = Kd_tree_search_knn(Kd_tree, [6,3.1], 2);

%% 使用data建立Kd树
function [tree] = Kd_tree_create(data)
% 生成Kd树,每次分割以方差最大的维度进行分割
[num, dimension] = size(data);
dimension = dimension - 1;
for i = 1: dimension
    data_var(i) = var(data(:,i));
end
[~, choose_dim] = max(data_var);
data = sortrows(data, choose_dim);
tree.id = data(round(num/2),end);
tree.node = data(round(num/2),1:end-1);
tree.dim = choose_dim;
tree.parent = [];
tree.left = [];
tree.right = [];

% 递归生成左右子树
lefttree = [];
righttree = [];
if round(num/2) > 1
    leftdata = data(1:(round(num/2)-1), :);
    lefttree = Kd_tree_create(leftdata);
    for i = 1: size(lefttree, 1)
        if isempty(lefttree(i).parent)
            lefttree(i).parent = tree.id;
            tree.left = lefttree(i).id;
        end
    end
end
if round(num/2) < num
    rightdata = data((round(num/2)+1):end, :);
    righttree = Kd_tree_create(rightdata);
    for i = 1: size(righttree, 1)
        if isempty(righttree(i).parent)
            righttree(i).parent = tree.id;
            tree.right = righttree(i).id;
        end
    end
end
tree = [tree; lefttree];
tree = [tree; righttree];
end


%% 利用Kd树进行kNN查询
function [closest_point] = Kd_tree_search_knn(Kd_tree, data, n)
% 从根节点开始一直查询到叶节点,找到和data在一个区域的叶节点
closest = Kd_tree(1);
while(1)
    if closest.node(closest.dim) >= data(closest.dim) && ~isempty(closest.left)
        closest = Kd_tree(find([Kd_tree.id]==closest.left));
    elseif closest.node(closest.dim) <= data(closest.dim) && ~isempty(closest.right)
        closest = Kd_tree(find([Kd_tree.id]==closest.right));
    else
        break
    end
end

Kd_tree(find([Kd_tree.id]==closest.id)).done = 1;
closest_point = closest.node;
[max_dis, max_idx] = max(sum((closest_point - data).^2, 2));
max_dis = max_dis(1);
max_idx = max_idx(1);

% 从当前节点向上回溯
node_now = closest;
while(1)
    % 回溯到根节点就break
    if find([Kd_tree.id]==node_now.id) == 1
        break
    end
    
    % 回溯到父节点,如果父节点的点符合要求就添加进去
    node_now = Kd_tree(find([Kd_tree.id]==node_now.parent));
    Kd_tree(find([Kd_tree.id]==node_now.id)).done = 1;
    if size(closest_point, 1) < n
        closest_point(end+1, :) = node_now.node;
    elseif sum((node_now.node-data).^2) < max_dis
        closest_point(max_idx, :) = node_now.node;
        [max_dis, max_idx] = max(sum((closest_point - data).^2, 2));
        max_dis = max_dis(1);
        max_idx = max_idx(1);
    end
    
    % 检查data点到父节点的分割线的距离,如果距离小于当前最大距离,则可能在另一侧有符合要求的点
    closest_temp = [];
    if (data(node_now.dim)-node_now.node(node_now.dim))^2 < max_dis
        if ~isempty(node_now.left)
            node_temp = Kd_tree(find([Kd_tree.id]==node_now.left));
            if isempty(node_temp.done)
                % 把左子节点调到第一行,作为根节点,递归调用
                Kd_tree_temp = Kd_tree;
                Kd_tree_temp(1) = node_temp;
                Kd_tree_temp(find([Kd_tree.id]==node_temp.id)) = Kd_tree(1);
                closest_temp = [closest_temp; Kd_tree_search_knn(Kd_tree_temp, data, n)];
            end
        end
        if ~isempty(node_now.right)
            node_temp = Kd_tree(find([Kd_tree.id]==node_now.right));
            if isempty(node_temp.done)
                % 把右子节点调到第一行,作为根节点,递归调用
                Kd_tree_temp = Kd_tree;
                Kd_tree_temp(1) = node_temp;
                Kd_tree_temp(find([Kd_tree.id]==node_temp.id)) = Kd_tree(1);
                closest_temp = [closest_temp; Kd_tree_search_knn(Kd_tree_temp, data, n)];
            end
        end
    end
    
    if ~isempty(closest_temp)
        closest_temp_dis = sum((closest_temp - data).^2, 2);
        for i = 1: size(closest_temp_dis, 1)
            if closest_temp_dis(i) < max_dis
                closest_point(max_idx, :) = closest_temp(i, :);
                [max_dis, max_idx] = max(sum((closest_point - data).^2, 2));
                max_dis = max_dis(1);
                max_idx = max_idx(1);
            end
        end
    end
end
end
使用matlab建立Kd-tree及最近邻查询 之前写过一篇使用matlab建立Kd-tree并进行k-NN查询。之前写完之后没怎么测试就直接丢上来了,这些天有人后台私信问相关的问题后才发现搜索算法的实现好像有一些问题,而且整体代码比较杂乱,想着重新实现一遍,因此有了这篇。 阅读详情

相关推荐

DBSCAN算法在风电-负荷场景削减中的应用与实践

密度聚类是处理复杂数据分布的重要机器学习技术,其中DBSCAN算法因其自动识别噪声点和任意形状簇的能力而广受关注。该算法通过定义邻域半径(ε)和最小样本数(MinPts)两个核心参数,实现基于密度的空间聚类。在电力系统领域,DBSCAN特别适用于风电出力与负荷需求这类具有时空耦合特性的多维数据。通过MATLAB实现,可以高效完成数据标准化、特征向量构建、参数优化等关键步骤。实际工程中,该方法相比传统K-means等算法,在保留原始数据统计特征方面表现更优,概率分布误差可降低37%以上。典型应用场景包括新能源

weixin_34162228的博客 369

使用matlab实现KD-TREE与BBF算法的结合.zip

matlab算法,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。

matlab KD树的使用【2024最新版】

KD树的使用。博客长期更新,本文最近一次更新时间为:2024年11月9日。

点云侠的博客 4918

Matlab构建KD树

机器学习、构建kd树

qq_36638788的博客 1391

【信息科学与工程学】【控制科学】第十二篇 微型计算机控制技术01

更精确的经典模型:I1在第5周期WB结束,I2最早可在第6周期进入EX,但I2在ID阶段就需要R1,因此I2的ID需在第6周期,而I1的WB在第5周期,所以I2的ID可以紧接在第6周期,但中间仍有一个stall(因为I1的EX结果要等到MEM之后才能转发给ID?有优先级继承后,Task_L被提升优先级,不会被Task_M抢占,阻塞时间缩短为Task_L剩余执行时间(9ms),仍可能超过10ms,但可通过调整任务周期或使用中断处理缓解。电感L=10μH,输出电容C=100μF,ESR=5mΩ。

weixin_49199313的博客 8630

【信息科学与工程学】【数据科学】第十八篇 数值分析 系列二 数值算法设计01

编号类型领域问题问题的数学分析及数值分析算法逐步推理思考的数学表达式参数列表及参数的边界范围及条件及常数关联知识1数值积分数值逼近计算定积分 I=∫ab​f(x)dx的近似值。数学分析:将积分区间等分,利用插值多项式近似被积函数,构造机械求积公式。数值分析:Newton-Cotes公式是等距节点的插值型求积公式。高阶公式(n≥8)因Cotes系数有正负,数值不稳定。偶阶公式(如Simpson)具有n+1次代数精度。为提高精度,常采用复化求积法(将区间细分后应用低阶公式)。

weixin_49199313的博客 158

【Matlab】基于KDtree的最近邻搜索和范围搜索

rangesearch() —— 根据给定k-维数据集,返回指定距离范围内的所有数据点。摘要:介绍Matlab的rangesearch()函数和knnsearch()函数。knnsearch() —— 根据给定k-维数据集,返回最近的K个数据点。

我的乌托 1045

【信息科学与工程学】计算机科学与自动化—第十五篇 云计算 11 算法篇01

编号类型领域问题问题的数学分析(含几何学/拓扑学/代数学/数论/集合论/离散数学/概率论/统计学/其他)及数值分析及算法分析及参数列表及参数数值设计C/C++/rust/python代码软件(含编译器)及硬件资源需求(CPU/GPU/内存【NAND/DRAM/HBM/其他】/HBM、HDD、SSD、RAID卡、其他)关联知识1工作负载调度数据中心最小化总完成时间/成本。

weixin_49199313的博客 217

matlab中kdtree调用,搜索点云数据近邻点

结合xyz点云数据,调用matlab中kdtree进行搜索近邻点,其中包括一次性对所有点进行k近邻点搜搜,以及针对单个点进行kdtree的搜搜两种情况。

Matlab中点云处理之KD树的应用

点云是三维空间中一组离散的点的集合,常用于三维物体的建模和分析。在点云处理的过程中,快速的搜索和查询是非常重要的一部分。通过构建KD树,我们可以实现高效的搜索和查询,进而应用于诸如点云分析、匹配等领域。KD树是一个二叉树,每个节点表示数据的一个样本点,树的分割超平面按照特征维度选择,将样本点划分到不同的子节点中。接下来,我们使用Matlab中的kdsearch函数进行点云的搜索和查询。首先,我们需要准备一个点云数据集。通过以上代码,我们可以得到查询点在点云数据集中的最近邻居点,同时将其可视化展示出来。

QsPascal的博客 403

KD树在计算机科学和机器学习领域中有着广泛的应用,它可以用于解决各种问题,如最近邻搜索、范围查询和聚类等。本文将介绍KD树的基本概念及其在Matlab中的应用。

KD树是一种二叉树结构,它可以对k维数据进行快速的查找和排序。分割的方法是通过选择一个轴来实现的,通常选择方差最大的轴作为分割轴。例如,在二维空间中,如果有很多点的x轴方差比y轴方差大,则选择x轴作为分割轴。在Matlab中,我们可以轻松地实现KD树的构建和最近邻搜索。除了最近邻搜索,KD树还可以应用于范围查询和聚类等问题。因此,掌握KD树的原理和应用是非常有价值的。KD树在计算机科学和机器学习领域中有着广泛的应用,它可以用于解决各种问题,如最近邻搜索、范围查询和聚类等。% 计算节点和目标点的距离。

学习使你进步。 583

基于KDtree的电路故障检测算法的MATLAB仿真

目录1.算法描述2.仿真效果预览3.MATLAB核心程序4.完整MATLAB k-d树是每个节点都为k维点的二叉树。所有非叶子节点可以视作用一个超平面把空间分割成两个半空间。节点左边的子树代表在超平面左边的点,节点右边的子树代表在超平面右边的点。选择超平面的方法如下:每个节点都与k维中垂直于超平面的那一维有关。因此,如果选择按照x轴划分,所有x值小于指定值的节点都会出现在左子树,所有x值大于指定值的节点都会出现在右子树。这样,超平面可以用该x值来确定,其法线为x轴的单位向量。1.对KDtree

fpga/matlab/simulink算法仿真工程 741

结合KD-TREE与BBF算法的Matlab实战项目

KD-TREE(K-Dimensional Tree)是一种用于组织和查询点在K维空间中分布的数据结构。它是一种二叉树,用于处理多维数据中的搜索问题,尤其是当数据点需要进行范围查询、最近邻搜索或插值时。在机器学习、计算机图形学、空间数据库和数据压缩等领域有广泛的应用。在机器学习中,KD-TREE常用于分类、回归和其他各种优化问题,如K-近邻(K-Nearest Neighbors, KNN)算法中作为快速检索最近邻点的基础。

weixin_35794316的博客 717

机器学习 KD树_递归搜索(matlab实现)

文章目录思路效果代码mianKd_Tree_CreaterecursiveKd_Tree_Search 思路 KD书基本思路: 建立KD树(Kd_Tree_Create) 递归搜索:回溯搜索的起点(Kd_Tree_Search) 回溯搜索:收敛到全局最近点(暂未实现) 效果 仅用递归搜索效果如下: 代码 mian clear all; clc; %% 数据导入 Dataset=csvread("iris_dataset.csv"); rows=150; columns=5; %% 数据分割 Train_

dc12499574的博客 1432

kd-树matlab程序

完全使用matlab编写的kd-tree程序。 完全使用matlab编写的kd-tree程序。 完全使用matlab编写的kd-tree程序。 完全使用matlab编写的kd-tree程序。

Kd Tree(MATLAB)K近邻法

Kd Tree(MATLAB) K近邻法 包含Kd树生成、KNN查找算法、以及相应的函数实例 Kd tree 生成函数采用方差法与特征序号递增法两种实现 参考书籍:统计学习方法--李航 欢迎讨论学习

机器学习 KD树_递归_回溯_搜索(matlab实现)

文章目录思路效果待优化代码mianKd_Tree_CreaterecursiveKd_Tree_SearchKd_Tree_Recall_Search 思路 第一个版本:链接 KD书基本思路: 建立KD树(Kd_Tree_Create) 递归搜索:回溯搜索的起点, 建立回溯栈(Kd_Tree_Search) 回溯搜索:从起点向着根节点回溯 设 测试节点:test_x 当前最优节点:predicted_x_point 当前最短距离:predicted_x_distance 当前回溯节点:cuurent_poi

dc12499574的博客 1839

matlab中kdtree的搜索近邻点

主要包括对多有点搜索近邻点以及针对单个点搜索近邻点两种情况,给出详细的案例说明

上一篇: 使用matlab进行RANSAC直线检测
下一篇: 使用matlab进行K-means聚类
john_xia
博客等级 码龄8年 92粉丝 25原创
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值