python实现kd树以及最近邻查找算法

算法(1):KD树的原理与基本代码 由于在做项目时遇到平面内最近点求解的问题,需要用到KD树简化算法,减少计算资源,因此本文记录这个过程中学到的知识。 阅读详情

一、kd树简介

kd树是一种树形结构,树的每个节点存放一个k维数据,某一节点的子节点可以看作是由过该节点一个平面切割后产生的(想象一下切蛋糕的过程),如此反复产生切割平面,就能为每个数据在空间中建立索引,如下图所示:
在这里插入图片描述
由于采用这种特殊的分割方式,使得在利用kd树做最近邻查找时,可以避开一些距离很远的点,查找速度得到了较大的提升,对于空间中N个k维数据,穷举法的算法复杂度为O(Nk),而使用kd树查找的算法复杂度只有O(klog(N))。kd树是一种典型的空间换时间的方式,即花费存储空间为数据建立索引,这样使得后续查找时速度更快,花费时间更少。

二、kd树生成

具体的算法实现主要参考的是这篇文章:https://www.cnblogs.com/eyeszjwang/articles/2429382.html,实现时有少量改动。生成kd树有两个关键的中间过程,即:

1.确定切分域

(1)确定split域:对于所有描述子数据(特征矢量),统计它们在每个维上的数据方差。以SURF特征为例,描述子为64维,可计算64个方差。挑选出最大值,对应的维就是split域的值。数据方差大表明沿该坐标轴方向上的数据分散得比较开,在这个方向上进行数据分割有较好的分辨率;

这段文字用通俗一点的语言来说就是:对于二维的情况,每一次做数据切分的时候,沿着x轴还是y轴做切分是一个问题,那么我们要怎么确定呢?我们可以统计这些二维数据的x值和y值的方差,方差越大说明数据在这一方向上越离散,而数据越离散说明沿着这一方向上数据之间的距离区分度越大,简单点来说就是相互之间隔得更远,我们就用这个方向做切分。
确定了切分域之后,我们就需要来对数据做切分了。

2.确定数据域

(2)确定Node-data域:数据点集Data-set按其第split域的值排序。位于正中间的那个数据点被选为Node-data。此时新的Data-set’ = Data-set\Node-data(除去其中Node-data这一点)。

简单来说,这句话的意思是:现在我们已经确定了沿着x轴做切分,那么我们要怎么决定在x轴哪里做切分呢?我们可以将所有数据根据x值的大小做一个排序,然后选取正中间那个数据的x值作为切分的位置。注意,这里有一个关键的问题是:如果我们有偶数个数据,怎么确定中间那个数据?难道我们选取中间两个数做一下平均???如果没有记错的话这应该是中位数的定义。。。如果这样完全就是自找麻烦!因为我们要确保至少有一个数据的x值落在切分点上,但是取平均之后并不能保证!!!所以更好的办法是,在有两个中间数据的情况下,随便选取一个数据的x值就行了。
决定了在x轴哪里做切分之后,我们就需要把数据做切分了,这里根据数据的x值相对于切分位置的大小,可以归为左节点和右节点,同时不要忘了:当前主节点也要保存一个数据,选取一个x值大小和切分位置相等的数据保存就行(如果有多个随便选一个就行,关键之处在于这个数据的x值落在切割线上。)

3.理解递归树

前面提到过,kd树是一种树形结构,因此可以递归生成,这是树形结构的共性,用程序语言来说,递归就是函数自己调用自己,在理解上也是很自然的。对于一组数据,我们通过找到的一个切分线把数据一分为二,而这个切分线的确定只和这组数据有关,左边的数据归为左节点,右边的数据归为右节点,更进一步,对于左边或者右边的这组数据,我们又可以将其看作一个整体,找到一个切分线把它一分为二,这样将一组数据一分为二的过程反复进行,相当于这个过程函数不断地调用自身,最终生成二叉树,将所有的数据分开。

4.python实现递归树代码

###建立kd树和实现查询功能
import numpy as np
import matplotlib.pyplot as plt

class kdTree:
    def __init__(self, parent_node):
        '''
        节点初始化
        '''
        self.nodedata = None   ###当前节点的数据值,二维数据
        self.split = None ###分割平面的方向轴序号,0代表沿着x轴分割,1代表沿着y轴分割
        self.range = None  ###分割临界值
        self.left = None    ###左子树节点
        self.right = None   ###右子树节点
        self.parent = parent_node  ###父节点
        self.leftdata = None  ###保留左边节点的所有数据
        self.rightdata = None ###保留右边节点的所有数据
        self.isinvted = False ###记录当前节点是否被访问过

    def print(self):
        '''
        打印当前节点信息
        '''
        print(self.nodedata, self.split, self.range)

    def getSplitAxis(self, all_data):
        '''
        根据方差决定分割轴
        '''
        var_all_data = np.var(all_data, axis=0)
        if var_all_data[0] > var_all_data[1]:
            return 0
        else:
            return 1
    

    def getRange(self, split_axis, all_data):
        '''
        获取对应分割轴上的中位数据值大小
        '''
        split_all_data = all_data[:, split_axis]
        data_count = split_all_data.shape[0]
        med_index = int(data_count/2)
        sort_split_all_data = np.sort(split_all_data)
        range_data = sort_split_all_data[med_index]
        return range_data


    def getNodeLeftRigthData(self, all_data):
        '''
        将数据划分到左子树,右子树以及得到当前节点
        '''
        data_count = all_data.shape[0
KNN-KD树 KNN-KD树学习笔记之前已经介绍过KNN的算法了,回顾一下KNN的算法核心思想:KNN算法是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分类到这个类中。实现kNN算法时,主要考虑的问题是如何对训练数据进行快速k近邻搜索,这点在特征空间的维数大以及训练数据容量大时尤其重要。简单的KNN算法需要遍历整个训练数据集来求解距离, 阅读详情

相关推荐

机器学习knn算法实现详解

𝑘近邻法是基本且简单的分类与回归方法。𝑘近邻法的基本做法是:对给定的训练实例点和输入实例点,首先确定输入实例点的,然后利用这𝑘个训练实例点的类的多数来预测输入实例点的类。𝑘近邻模型对应于基于训练数据集对特征空间的一个划分。𝑘近邻法中,当训练集、距离度量、𝑘值及分类决策规则确定后,其结果唯一确定。

m0_61937687的博客 2001

03 k近邻法——Python实现

一、求最近邻点: 题目: T={(2,3)T,(5,4)T,(9,6)T,(4,7)T,(8,1)T,(7,2)T}T=\begin{Bmatrix} (2,3)^T,(5,4)^T,(9,6)^T,(4,7)^T,(8,1)^T,(7,2)^T \end{Bmatrix}T={(2,3)T,(5,4)T,(9,6)T,(4,7)T,(8,1)T,(7,2)T​} Python代码: # a...

yuxy411的博客 493

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

作为机器学习中一种基本的分类方法,K近邻(KNN)法是一种相对简单的方法。其中一个理由是K近邻法不需要对训练集进行学习。然而,不需要对训练集进行学习,反过来也会造成对测试集进行判定时,计算与空间复杂度的增加。 K近邻法最简单的实现方法是对需要分类的目标点,计算出训练集中每一个点到其的距离(比较常用的有欧氏距离),然后选取K个距离目标最近的点,根据这些点的分类以多数表决的形式来决定目标点的分类。理

反魂蝶,八分咲 9367

【机器学习】 多维kd-tree的python实现

本篇主要介绍一个用python实现kd-tree的代码,以及围绕代码实现的kd-tree原理。期望能够为读者打开另一个视角,看待kd-tree的好处。

gongdiwudu的专栏 7924

【Python KD树搜索】——构建高效的数据结构实现近邻搜索

通过这种方式,KD树将数据点分布在一颗平衡的二叉树中,使得最近邻查询的时间复杂度可以达到O(logn),相较于线性扫描的复杂度O(n)更加高效。为了评估KD树的性能,我们需要考虑三个因素:数据集的维度、查询点的数量和数据集的大小。通常情况下,随着数据集的维度增加,KD树的性能会迅速下降,因为高维空间中数据点的数量呈指数级增长。通过本文的介绍,您应该已经了解了如何使用Python KD树搜索来构建高效的数据结构,并如何度量算法的性能。通过测试不同维度的数据集,我们可以对KD树的性能有一个初步的认识。

. 885

ERDAS 2022与ArcGIS共存安装教程:如何避免端口冲突(详细配置步骤)

本文提供了一份详细的ERDAS 2022与ArcGIS共存安装教程,核心在于解决两者因FlexNet许可证服务器导致的端口冲突问题。通过分步指导,包括检查现有端口占用、修改ERDAS许可证文件端口号、配置防火墙及客户端设置,确保两款专业GIS与遥感软件能在同一系统上稳定运行。

weixin_29279047的博客 253

GitLab社区版vs企业版:本地部署性能对比与选型建议(含实测数据)

本文深入对比GitLab社区版(CE)与企业版(EE)在本地部署中的性能差异与功能特性,提供实测数据与选型建议。测试显示EE版在并发克隆、CI流水线启动等场景性能提升显著,尤其适合需要高级安全合规与CI/CD功能的团队。文章还包含硬件配置指南与成本效益分析,帮助技术决策者做出明智选择。

weixin_28828243的博客 295

Jetson Orin NX上PyTorch环境搭建与性能优化指南

本文详细指导如何在Jetson Orin NX上搭建高效的PyTorch开发环境。内容涵盖CUDA与cuDNN的“隐藏”配置、Miniconda虚拟环境管理、PyTorch for Jetson的正确安装与验证,并提供了电源模式设置、TensorRT加速、混合精度等关键性能优化实战技巧,帮助开发者充分释放边缘AI设备的算力。

weixin_29090089的博客 337

RK3566基于Buildroot定制QT开发环境的完整指南

本文详细介绍了如何在RK3566开发板上使用Buildroot定制QT开发环境的完整流程。从基础环境搭建、Buildroot初始配置到QT模块选择与编译验证,提供了实战经验和常见问题解决方案,帮助开发者高效完成嵌入式Linux下的QT开发环境部署。

weixin_26804345的博客 358

实现labelme批量json_to_dataset方法

labelme可以帮助我们快速的实现Mask-RCNN中数据集json文件的生成,然而还需要我们进一步的将json转成dataset,可以直接在cmd中执行labelme_json_to_dataset.exe C:\Users\Administrator\Desktop\total\1.json(路径),但是这个过程需要我们一个json文件的生成,过程很慢。 一、打开abelm...

简简单单 5万+

226届数字IC秋招笔试面试全攻略

本文系统介绍了数字IC设计岗位面试的核心技巧,聚焦三大关键环节:自我介绍、项目介绍和技术问题回答。在自我介绍部分,强调1-2分钟结构化表达,突出与岗位匹配的技能和量化成果;项目介绍环节提出"背景-职责-技术-难点-成果"五步框架,建议结合架构图和性能数据展示技术深度;技术问题回答策略包括理解问题、结构化思考、举例说明和诚实应对未知。文章还提供了项目包装方法,指导如何通过量化数据、架构创新展示和技术难点解决方案来突出项目亮点,并附有简历项目描述示例和技术问题回答模板,帮助面试者全方位展示专

2301_79143213的博客 1062

ETAS工具导入DBC生成Com协议栈

ETAS工具导入DBC主要也是生成arxml用的,ETAS推荐使用Cobra导入,本文介绍导入过程及注意事项不管是导入DBC还是arxml,本质上都是为了生成对应的com协议栈,目的是为了减少重复的工作量,所以,前期定义好收发的矩阵很重要,一般导入一次之后,后面就可以按变更点手动更改了。

赞的博客 1711

25、格式化字符串攻击全解析

本文深入解析了格式化字符串攻击的原理与利用方式,涵盖缓冲区溢出与格式化字符串漏洞的区别,详细介绍了printf函数的工作机制、常见格式化说明符及其安全隐患。文章分析了三类典型编程错误导致的漏洞,并展示了如何通过恶意格式化字符串实现拒绝服务、内存读取和写入攻击。同时,提供了有效的防御措施,包括输入验证、使用安全函数、避免直接使用用户输入作为格式化字符串以及启用编译器安全选项,帮助开发者防范此类高危漏洞。

beer8的博客 83

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

上一篇: python实现共轭梯度算法
下一篇: 高斯过程回归(Gaussian Processes Regression, GPR)简介
哆啦A梦PLUS
博客等级 码龄7年 75粉丝 17原创
评论 15
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值