这里将写了一个KDTree类,仅实现了最近邻,K近邻之后若有时间再更新:

from collections import namedtuple
from operator import itemgetter
from pprint import pformat
import numpy as np class Node(namedtuple('Node', 'location left_child right_child')):
def __repr__(self):
return pformat(tuple(self)) class KDTree():
def __init__(self, points):
self.tree = self._make_kdtree(points)
if len(points) > 0:
self.k = len(points[0])
else:
self.k = None def _make_kdtree(self, points, depth=0):
if not points:
return None k = len(points[0])
axis = depth % k points.sort(key=itemgetter(axis))
median = len(points) // 2 return Node(
location=points[median],
left_child=self._make_kdtree(points[:median], depth + 1),
right_child=self._make_kdtree(points[median + 1:], depth + 1)) def find_nearest(self,
point,
root=None,
axis=0,
dist_func=lambda x, y: np.linalg.norm(x - y)): if root is None:
root = self.tree
self._best = None # 若不是叶节点,则继续向下走
if root.left_child or root.right_child:
new_axis = (axis + 1) % self.k
if point[axis] < root.location[axis] and root.left_child:
self.find_nearest(point, root.left_child, new_axis)
elif root.right_child:
self.find_nearest(point, root.right_child, new_axis) # 回溯:尝试更新 best
dist = dist_func(root.location, point)
if self._best is None or dist < self._best[0]:
self._best = (dist, root.location) # 若超球与另一边超矩形相交
if abs(point[axis] - root.location[axis]) < self._best[0]:
new_axis = (axis + 1) % self.k
if root.left_child and point[axis] >= root.location[axis]:
self.find_nearest(point, root.left_child, new_axis)
elif root.right_child and point[axis] < root.location[axis]:
self.find_nearest(point, root.right_child, new_axis) return self._best

测试:

point_list = [(2, 3, 3), (5, 4, 4), (9, 6, 7), (4, 7, 7), (8, 1, 1), (7, 2, 2)]
kdtree = KDTree(point_list) point = np.array([5, 5, 5])
print(kdtree.find_nearest(point))

输出:

(1.4142135623730951, (5, 4, 4))

与 Scikit-Learn 性能对比(上是我的实现,下是 Scikit-Learn 的实现):

可以看到仅相差 1 毫秒,所以性能说得过去。

(本文完)

Python 实现 KD-Tree 最近邻算法的更多相关文章

  1. K-D TREE算法原理及实现

    博客转载自:https://leileiluoluo.com/posts/kdtree-algorithm-and-implementation.html k-d tree即k-dimensional ...

  2. k-d tree算法

    k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点匹配的时候就会利用到k ...

  3. 【数据结构与算法】k-d tree算法

    k-d tree算法 k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据结构.主要应用于多维空间关键数据的搜索(如:范围搜索和最近邻搜索). 应用背景 SIFT算法中做特征点 ...

  4. Python机器学习笔记 K-近邻算法

    K近邻(KNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一. 所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表.KNN算法的 ...

  5. [转载]kd tree

    [本文转自]http://www.cnblogs.com/eyeszjwang/articles/2429382.html k-d树(k-dimensional树的简称),是一种分割k维数据空间的数据 ...

  6. k-d tree 学习笔记

    以下是一些奇怪的链接有兴趣的可以看看: https://blog.sengxian.com/algorithms/k-dimensional-tree http://zgjkt.blog.uoj.ac ...

  7. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

  8. Python之路,Day21 - 常用算法学习

    Python之路,Day21 - 常用算法学习   本节内容 算法定义 时间复杂度 空间复杂度 常用算法实例 1.算法定义 算法(Algorithm)是指解题方案的准确而完整的描述,是一系列解决问题的 ...

  9. K-D Tree题目泛做(CXJ第二轮)

    题目1: BZOJ 2716 题目大意:给出N个二维平面上的点,M个操作,分为插入一个新点和询问到一个点最近点的Manhatan距离是多少. 算法讨论: K-D Tree 裸题,有插入操作. #inc ...

  10. [Python]基于K-Nearest Neighbors[K-NN]算法的鸢尾花分类问题解决方案

    看了原理,总觉得需要用具体问题实现一下机器学习算法的模型,才算学习深刻.而写此博文的目的是,网上关于K-NN解决此问题的博文很多,但大都是调用Python高级库实现,尤其不利于初级学习者本人对模型的理 ...

随机推荐

  1. plsql 永久注册码适用个版本

    注册码:Product Code:4t46t6vydkvsxekkvf3fjnpzy5wbuhphqzserial Number:601769 password:xs374ca

  2. Alibaba Java开发手册索引规约学习笔记

    最近一段时间再看阿里巴巴 Java开发手册索引规约,写篇帖子总结一下,索引规约内容如下 为了通用,更为了避免造数据的痛苦,文中所涉及表.数据,均来自于MySQL官网提供的示例库employees,可通 ...

  3. 构建之法助教园地第一次作业--点评<西北师范大学|李晓婷>

    一 博客点评 第一次作业--准备篇:https://www.cnblogs.com/Mookiepiece/p/10464606.html#4192515 点评内容: 首先,你对电脑很感兴趣,兴趣就是 ...

  4. loadrunner 添加集合点和添加压力机

    loadrunner 添加集合点和添加压力机 一.添加集合点: 1.在脚本中右键insert--rendezvous (集合点一定要添加在事务的外面,否则影响事务准确性) 2.创建controller ...

  5. node-fs文件系统模块

    在node环境中所有与文件操作都是通过fs核心模块实现的.包括文件的创建.删除.查询以及读写和写入 在 fs 模块中,所有的方法都分为同步和异步两种实现,具有 sync 后缀的方法为同步方法,不具有 ...

  6. linxu下redis安装实战

    redis官网地址:http://www.redis.io/ 最新版本:2.8.3 在Linux下安装Redis非常简单,具体步骤如下(官网有说明): 1.下载源码,解压缩后编译源码. $ wget ...

  7. python3 练手实例2 解一元二次方程组

    import math def y(): a,b,c=map(float,input('请输入一元二次方程式ax^2+bx+c=0,abc的值,用空格隔开:').split()) d=math.pow ...

  8. 深入理解line-height与vertical-align——前端布局常用属性

    line-height.font-size.vertical-align是设置行内元素布局的关键属性.这三个属性是相互依赖的关系,改变行间距离.设置垂直对齐等都需要它们的通力合作.下面将主要介绍lin ...

  9. Java装箱的 " == " 的问题

    装箱和拆箱  packagecom.xzj.Test; ​ /* * @ author thisxzj * @ create 2019-02-25 10:56 */ publicclassBase{  ...

  10. 如何识别Studio 5000程序开发版本号

    前言:中.大型AB PLC的编程软件从以前的RSLogix 5000到目前的Studio 5000,都是有版本号的,如RSLogix 5000 V19.0.Studio 5000 V32.高版本的软件 ...