写KD树的时候没把类别考虑进去。。。所以先用KD算出最近的k个点,然后找到对应分类最后输出占比最大的

KD树是一种二叉树,用来分割空间上得点

一个树节点的结构如下:

class TreeNode:

index = -1 # 对应维度序号

point = None # 对应的点

left = None # 左子树

right = None # 右子树

data = None

def __init__(self, index=-1, point=None, left=None, right=None):

self.index = index

self.point = point

self.left = left

self.right = right

def set_data(self, data):

self.data = data

def get_data(self):

return self.data

建树过程是:

先选出方差最大的维度

将现有数据按该维度排序

取数据中位点

中位点即该树结点的数据

点坐标左边的的传入左子树构造方法,右边的同理

下一层树结点使用下一个维度

代码:

def build_tree(self, dataset, split):

# 如果为空返回None

if dataset is None or len(dataset) is 0:

return None

# 顺序维度超出维度范围取余

if split >= len(dataset[0]) - 1:

split %= len(dataset[0]) - 1

# 如果仅只有一个点那么必定是叶子

if len(dataset) is 1:

return TreeNode(split, dataset[0], None, None)

data_sum = len(dataset)

dataset.sort(key=lambda x: x[split])

node = TreeNode()

node.index = split

point_index = int(data_sum / 2)

node.point = dataset[point_index]

node.left = self.build_tree(dataset[0:point_index], split + 1)

node.right = self.build_tree(dataset[point_index + 1:], split + 1)

return node

def create(self, dataset):

starlin = self.get_var(dataset)

root = self.build_tree(dataset, starlin)

self.root = root

return root

有时候check后的数据需要插入到树中:

插入的过程较简单,从root开始 按该层维度,大于该层维度的值的继续搜索左子树,反之右子树

直到搜索的节点为None 则在这里插入新的结点

def insert(self, point):

if self.root is None:

print('Build a tree first !')

return

if len(point) is not len(self.root.point):

print('This point have {l} splits but tree have {m}'.format(l=len(point), m=len(self.root.point)))

return

flag = False

root = self.root

while not flag:

if point[root.index] < root.point[root.index]:

if root.left is not None:

root = root.left

else:

split = (root.index + 1) % len(point)

root.left = TreeNode(split, point, None, None)

flag = True

else:

if root.right is not None:

root = root.right

else:

split = (root.index + 1) % len(point)

root.right = TreeNode(split, point, None, None)

flag = True

寻找过程,首先先按照插入的方法找到最接近的最底层子节点

然后依次向上回溯查找,如果该结点的另半个子树也可能成为最近点则将其Push进栈

查找至栈为空,则找到最近点。点间距离同理可应用不同的距离(相似度)算法

def sim_distance(self, p1, p2):

sum_of_squares = sum([pow(p1[i] - p2[i], 2) for i in range(len(p1))])

return sqrt(sum_of_squares)

def find_nearest(self, point):

root = self.root

s = Stack(99999)

while root is not None:

index = root.index

s.push(root)

if point[index] <= root.point[index]:

root = root.left

else:

root = root.right

nearest = s.pop()

min_dist = self.sim_distance(nearest.point, point)

while not s.isempty():

back_point = s.pop()

if back_point is None:

continue

index = back_point.index

if self.sim_distance([point[index]], [back_point.point[index]]) < min_dist:

if point[index] <= back_point.point[index]:

root = back_point.right

else:

root = back_point.left

s.push(root)

if min_dist > self.sim_distance(back_point.point, point):

nearest = back_point

min_dist = self.sim_distance(back_point.point, point)

return nearest.point, min_dist

KNN 算法的核心在于找到最近的k的点,然后根据这些点的类别缺点待查点的类别

我维护了一个长度始终为k的list来保存前k小得距离

每次跟 list尾部的进行比较,如果比其小则加入list,并排序 取前k项

def find_near_kth(self, point, k):

root = self.root

result = []

s = Stack(99999)

while root is not None:

index = root.index

s.push(root)

if point[index] <= root.point[index]:

root = root.left

else:

root = root.right

t_point = s.pop()

result.append((t_point, self.sim_distance(t_point.point, point)))

while not s.isempty():

back_point = s.pop()

if back_point is None:

continue

index = back_point.index

if self.sim_distance([point[index]], [back_point.point[index]]) <= result[len(result) - 1][1] or len(

result) < k:

if point[index] <= back_point.point[index]:

root = back_point.right

else:

root = back_point.left

s.push(root)

if result[len(result) - 1][1] > self.sim_distance(back_point.point, point) or len(result) < k:

result.append((back_point, self.sim_distance(back_point.point, point)))

result.sort(key=lambda x: x[1])

result = result[0:k]

return result

最后用了很蠢得方法来找对应点的分类:

def decide_type(kd_result, t_point, t_type):

ans = {i: 0 for i in t_type}

for node in kd_result:

for i in range(len(t_point)):

if node[0].point == t_point[i]:

ans[t_type[i]] += 1

break

max_v = 0

max_type = None

for i in ans:

if ans[i] > max_v:

max_v = ans[i]

max_type = i;

return max_type

测试如下:

kd = KdTree()

kd.create(train_point)

print(kd.find_near_kth((1, 1), 2))

# print(decide_type(kd.find_near_kth((6.5, 6), 3),train_point,train_type))

kd树 python实现_Python KD树实现+简单的KNN实现相关推荐

  1. kd树 python实现_Python - KDTree 实现

    KDTree 的 Python 实现. 1. KDTree 实现import numpy as np from scipy import spatial datas = np.array([[0,0, ...

  2. 二维正态分布图python代码_Python数据可视化正态分布简单分析及实现代码

    Python说来简单也简单,但是也不简单,尤其是再跟高数结合起来的时候... 正态分布(Normaldistribution),也称"常态分布",又名高斯分布(Gaussiandi ...

  3. python人像_python 使用OpenCV进行简单的人像分割与合成

    实现思路 通过背景建模的方法,对源图像中的动态人物前景进行分割,再将目标图像作为背景,进行合成操作,获得一个可用的合成影像. 实现步骤如下. 使用BackgroundSubtractorMOG2进行背 ...

  4. python手势识别_Python|使用opencv进行简单的手势检测

    简单的手势识别,基本思路是基于皮肤检测,皮肤的颜色在HSV颜色空间下与周围环境的区分度更高,从RGB转换到HSV颜色空间下针对皮肤颜色进行二值化,得到mask: defHSVBin(img): hsv ...

  5. kd树 python实现_kd树 寻找k近邻算法 python实现

    按照链接里的算法写了k近邻的python实现 from math import sqrt class KDnode: def __init__(self, data, left, right, spl ...

  6. python递归查找值返回_python – 从树递归中返回值列表

    我正在尝试自学数据结构,我正在用 Python实现一个k-d树.我有一种方法在我的k-d树类中的一个点的某个半径内搜索树中的点: def within_radius(self, point, radi ...

  7. KD树是什么? 为什么要用KD树? KD树怎么用? KD树和KNN的关联是什么?

    KD树是什么? 为什么要用KD树? KD树怎么用? KD树和KNN的关联是什么? sklearn中如何配置? 为了提高KNN的搜索效率,这里介绍一种可以减少计算距离次数的方法---KD树方法. KD树 ...

  8. kd树的根节点_kd树总结

    Kd-Tree,即K-dimensional tree,是一种高维索引树形数据结构,常用于在大规模的高维数据空间进行最近邻查找(Nearest Neighbor)和近似最近邻查找(Approximat ...

  9. 用python绘制树和森林_python实现画一颗树和一片森林

    本文实例为大家分享了python画一颗树和一片森林的具体代码,供大家参考,具体内容如下 实现效果 代码在这里 from turtle import Turtle def tree(plist, l, ...

最新文章

  1. Eclipse下搭建GitHub开发环境
  2. matplotlib将图绘制在多福图中
  3. 华为rh2285安装系统linux,华为2285h v5安装系统记
  4. CTF-Python打包成的exe文件Re逆向
  5. python找出在原图中的位置_用python简单处理图片(4):图像中的像素访问
  6. dj打碟怎么学_学DJ打碟 - Rane声卡连接
  7. C++ _stdcall和__stdcall、_fastcall的区别
  8. 禅道怎样添加开发人员
  9. 《白话大数据与机器学习》
  10. 又一股份制银行,菊风「视频能力平台」承包了
  11. UI自动化之分层思想pom模式
  12. C/C++银行账户管理系统
  13. 虚拟机批量克隆工具_如何使用老毛桃winpe进行克隆磁盘?
  14. html 设置表格间距 表格整体大小,css表格单元格间距怎么调整?
  15. MapX系列-- 开源Mitab
  16. 心理学实验程序编程(python)
  17. ZUCC_BB平台-Quiz B-3-7-答案
  18. 31、Flutter之Hero动画
  19. AD出现 “Net Tie failed verification”如何解决?
  20. java无参构造赋值怎么没用_Java有参构造方法和无参构造方法详解

热门文章

  1. python的print格式化输出,以及使用format来控制。
  2. Bert代码详解(一)重点详细
  3. LeetCode简单题之用栈操作构建数组
  4. CVD-ALD前驱体材料
  5. MindSpore循环神经网络
  6. 超轻量AI引擎MindSpore Lite
  7. 固件安全性—防止内存损坏和注入攻击
  8. 如何构建虚拟护士应用程序?
  9. 在Lumen中引入钉钉SDK
  10. [JAVAEE] Thymeleaf 基本语法: form相关标签