这里将写了一个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. Spring Boot学习总结二

    Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Redis还提供一些类 ...

  2. apue——无缓冲读写操作

    stdrw.c文件 #include "apue.h" #define BUFFSIZE 4096 #include <stdio.h> int main(int ar ...

  3. Python——合并指定文件夹下的所有excel文件

    前提:该文件夹下所有文件有表头且具有相同的表头. import glob # 同下 from numpy import * #请提前在CMD下安装完毕,pip install numppy impor ...

  4. CORS跨域 Ajax headers 问题

    今天我们遇到了一个CORS跨域的问题Ajax如下 var url = "http://localhost:11980/api/Demo/GetString"; //api地址 $. ...

  5. MySQL学习13 - 索引

    一.索引的介绍 二 .索引的作用 三.常见的几种索引: 3.1 普通索引 3.2 唯一索引 3.3 主键索引 3.4 组合索引 四.索引名词 五.正确使用索引的情况 什么是最左前缀呢? 六.索引的注意 ...

  6. webpack之proxyTable设置跨域

        可以看看这个视频中的介绍 :https://ke.qq.com/course/350693?tuin=f158ed6

  7. Oracle 里 case 和decode的简单用法

    case 就相想当于C#里面switch    l 列:根据员工的职位,计算加薪后的薪水数据 如果职位是Analyst , 加薪10% 如果职位是Programmer 加薪5% 如果职位是clerk ...

  8. JAVA进阶14

    间歇性混吃等死,持续性踌躇满志系列-------------第14天 1.线程的加入 package code0328; import javax.swing.*; import java.awt.* ...

  9. Python中区分函数和方法

    1.简单粗暴型: def func(): ... class Foo: def eat(self): print("吃") f = Foo() print(func) #<f ...

  10. 关于lnmp下 phalcon和tp框架下的nginx文件配置

    vim /etc/nginx/sites-available/default   进入修改目录 1.正常项目配置 server { listen 80 default_server; listen [ ...