kd树 求k近邻 python 代码
之前两篇随笔介绍了kd树的原理,并用python实现了kd树的构建和搜索,具体可以参考
kd树常与knn算法联系在一起,knn算法通常要搜索k近邻,而不仅仅是最近邻,下面的代码将利用kd树搜索目标点的k个近邻。
首先还是创建一个类,用于保存结点的值,左右子树,以及用于划分左右子树的切分轴
class decisionnode:
def __init__(self,value=None,col=None,rb=None,lb=None):
self.value=value
self.col=col
self.rb=rb
self.lb=lb
切分点为坐标轴上的中值,下面代码求得一个序列的中值
def median(x):
n=len(x)
x=list(x)
x_order=sorted(x)
return x_order[n//2],x.index(x_order[n//2])
然后按照左子树大于切分点,右子树小于切分点的规则构造kd树,其中data是输入的数据
#以j列的中值划分数据,左小右大,j=节点深度%列数
def buildtree(x,j=0):
rb=[]
lb=[]
m,n=x.shape
if m==0: return None
edge,row=median(x[:,j].copy())
for i in range(m):
if x[i][j]>edge:
rb.append(i)
if x[i][j]<edge:
lb.append(i)
rb_x=x[rb,:]
lb_x=x[lb,:]
rightBranch=buildtree(rb_x,(j+1)%n)
leftBranch=buildtree(lb_x,(j+1)%n)
return decisionnode(x[row,:],j,rightBranch,leftBranch)
接下来就是搜索树得到k近邻的过程,与搜索最近邻的过程大致相同,需要创建一个字典knears,用于存储k近邻的点以及与目标点的距离(欧氏距离)
搜索的过程为:
(1)第一步还是遍历树,找到目标点所属区域对应的叶节点
(2)从叶结点依次向上回退,按照寻找最近邻点的方法回退到父节点,并判断其另一个子节点对区域内是否可能存在k近邻点,具体的,在每个结点上进行以下操作:
(a)如果字典中的成员个数不足k个,将该结点加入字典
(b)如果字典中的成员不少于k个,判断该结点与目标结点之间的距离是否不大于字典中各结点所对应距离的的最大值,如果不大于,便将其加入到字典中
(c)对于父节点来说,如果目标点与其切分轴之间的距离不大于字典中各结点所对应距离的的最大值,便需要访问该父节点的另一个子节点
(3)每当字典中增加新成员,就按距离值对字典进行降序排序,将得到的列表赋值给poinelist,pointlist[0][1]便是字典中各结点所对应距离的最大值
(4)当回退到根节点并完成对其操作时,pointlist中后k个结点就是目标点的k近邻
代码如下:
#搜索树:输出目标点的近邻点
def traveltree(node,aim):
global pointlist #存储排序后的k近邻点和对应距离
if node==None: return
col=node.col
if aim[col]>node.value[col]:
traveltree(node.rb,aim)
if aim[col]<node.value[col]:
traveltree(node.lb,aim)
dis=dist(node.value,aim)
if len(knears)<k:
knears.setdefault(tuple(node.value.tolist()),dis)#列表不能作为字典的键
pointlist=sorted(knears.items(),key=lambda item: item[1],reverse=True)
elif dis<=pointlist[0][1]:
knears.setdefault(tuple(node.value.tolist()),dis)
pointlist=sorted(knears.items(),key=lambda item: item[1],reverse=True)
if node.rb!=None or node.lb!=None:
if abs(aim[node.col] - node.value[node.col]) < pointlist[0][1]:
if aim[node.col]<node.value[node.col]:
traveltree(node.rb,aim)
if aim[node.col]>node.value[node.col]:
traveltree(node.lb,aim)
return pointlist
完整代码在此处取
import numpy as np
from numpy import array
class decisionnode:
def __init__(self,value=None,col=None,rb=None,lb=None):
self.value=value
self.col=col
self.rb=rb
self.lb=lb #读取数据并将数据转换为矩阵形式
def readdata(filename):
data=open(filename).readlines()
x=[]
for line in data:
line=line.strip().split('\t')
x_i=[]
for num in line:
num=float(num)
x_i.append(num)
x.append(x_i)
x=array(x)
return x #求序列的中值
def median(x):
n=len(x)
x=list(x)
x_order=sorted(x)
return x_order[n//2],x.index(x_order[n//2]) #以j列的中值划分数据,左小右大,j=节点深度%列数
def buildtree(x,j=0):
rb=[]
lb=[]
m,n=x.shape
if m==0: return None
edge,row=median(x[:,j].copy())
for i in range(m):
if x[i][j]>edge:
rb.append(i)
if x[i][j]<edge:
lb.append(i)
rb_x=x[rb,:]
lb_x=x[lb,:]
rightBranch=buildtree(rb_x,(j+1)%n)
leftBranch=buildtree(lb_x,(j+1)%n)
return decisionnode(x[row,:],j,rightBranch,leftBranch) #搜索树:输出目标点的近邻点
def traveltree(node,aim):
global pointlist #存储排序后的k近邻点和对应距离
if node==None: return
col=node.col
if aim[col]>node.value[col]:
traveltree(node.rb,aim)
if aim[col]<node.value[col]:
traveltree(node.lb,aim)
dis=dist(node.value,aim)
if len(knears)<k:
knears.setdefault(tuple(node.value.tolist()),dis)#列表不能作为字典的键
pointlist=sorted(knears.items(),key=lambda item: item[1],reverse=True)
elif dis<=pointlist[0][1]:
knears.setdefault(tuple(node.value.tolist()),dis)
pointlist=sorted(knears.items(),key=lambda item: item[1],reverse=True)
if node.rb!=None or node.lb!=None:
if abs(aim[node.col] - node.value[node.col]) < pointlist[0][1]:
if aim[node.col]<node.value[node.col]:
traveltree(node.rb,aim)
if aim[node.col]>node.value[node.col]:
traveltree(node.lb,aim)
return pointlist def dist(x1, x2): #欧式距离的计算
return ((np.array(x1) - np.array(x2)) ** 2).sum() ** 0.5 knears={}
k=int(input('请输入k的值'))
if k<2: print('k不能是1')
global pointlist
pointlist=[]
file=input('请输入数据文件地址')
data=readdata(file)
tree=buildtree(data)
tmp=input('请输入目标点')
tmp=tmp.split(',')
aim=[]
for num in tmp:
num=float(num)
aim.append(num)
aim=tuple(aim)
pointlist=traveltree(tree,aim)
for point in pointlist[-k:]:
print(point)
kdtree
kd树 求k近邻 python 代码的更多相关文章
- K近邻python
有一个带标签的数据集X,标签为y.我们想通过这个数据集预测目标点x0的所属类别. K近邻算法是指在X的特征空间中,把x0放进去,然后找到距离x0最近的K个点.通过这K个点所属类别,一般根据少数服从多数 ...
- 统计学习三:2.K近邻法代码实现(以最近邻法为例)
通过上文可知k近邻算法的基本原理,以及算法的具体流程,kd树的生成和搜索算法原理.本文实现了kd树的生成和搜索算法,通过对算法的具体实现,我们可以对算法原理有进一步的了解.具体代码可以在我的githu ...
- K近邻 Python实现 机器学习实战(Machine Learning in Action)
算法原理 K近邻是机器学习中常见的分类方法之间,也是相对最简单的一种分类方法,属于监督学习范畴.其实K近邻并没有显式的学习过程,它的学习过程就是测试过程.K近邻思想很简单:先给你一个训练数据集D,包括 ...
- 机器学习_K近邻Python代码详解
k近邻优点:精度高.对异常值不敏感.无数据输入假定:k近邻缺点:计算复杂度高.空间复杂度高 import numpy as npimport operatorfrom os import listdi ...
- CodeForces - 1093G:Multidimensional Queries (线段树求K维最远点距离)
题意:给定N个K维的点,Q次操作,或者修改点的坐标:或者问[L,R]这些点中最远的点. 思路:因为最后一定可以表示维+/-(x1-x2)+/-(y1-y2)+/-(z1-z2)..... 所以我们可以 ...
- kNN(k近邻)算法代码实现
目标:预测未知数据(或测试数据)X的分类y 批量kNN算法 1.输入一个待预测的X(一维或多维)给训练数据集,计算出训练集X_train中的每一个样本与其的距离 2.找到前k个距离该数据最近的样本-- ...
- k临近法的实现:kd树
# coding:utf-8 import numpy as np import matplotlib.pyplot as plt T = [[2, 3], [5, 4], [9, 6], [4, 7 ...
- k近邻法的C++实现:kd树
1.k近邻算法的思想 给定一个训练集,对于新的输入实例,在训练集中找到与该实例最近的k个实例,这k个实例中的多数属于某个类,就把该输入实例分为这个类. 因为要找到最近的k个实例,所以计算输入实例与训练 ...
- 统计学习方法与Python实现(二)——k近邻法
统计学习方法与Python实现(二)——k近邻法 iwehdio的博客园:https://www.cnblogs.com/iwehdio/ 1.定义 k近邻法假设给定一个训练数据集,其中的实例类别已定 ...
随机推荐
- ES5给出的两个新增的语法糖getter和setter介绍
前言信息: EMCAScript5 简称ES5 ECMAScript是一种由Ecma国际(前身为欧洲计算机制造商协会,英文名称是European Computer Manufacturers Ass ...
- 重新想,重新看——CSS3变形,过渡与动画①
学习CSS3,觉得最难记忆的部分除了flex特性之外,就要属变形,过渡和动画部分了.作为初学者,总有种犯懒的心理,想着既然IE8浏览器都不完全支持CSS动画属性,还要考虑浏览器兼容问题,那么就不那么着 ...
- Mybatis动态SQL——if,where,trim,choose,set.foreach的用法
知识点:主要介绍mybatis中,动态sql中的if,where,trim,set,foreach的用法 自学谷粒学院mybatis学习视频,参考mybatis官方文档 java包:log4j.jar ...
- 在.Net中进行SQL Server数据库备份与还原操作实用类
#region 类说明 //----------------------------------------------------------------------------- // // 项目 ...
- ThinkPHP开发笔记-模型
1.模型定义.在ThinkPHP中,可以无需进行任何模型定义.只有在需要封装单独的业务逻辑的时候,模型类才是必须被定义的,因此ThinkPHP在模型上有很多的灵活和方便性,让你无需因为表太多而烦恼. ...
- webstorm的安装、激活码、更换主题颜色的修改、汉化
一.安装 1.解压webstorm11zh.rar,双击.exe文件,下一步安装,在安装结束前会提示输入激活码,这个从网上随便找一个可用的即可. 二.更换主题颜色: 1.先从网上找一个喜欢的主题颜色, ...
- js 图片查看器
将以前用angular 写的 自定义指令 封装成 插件,无需引用jquery.angular. 下载下来即可查看效果. github网址: https://github.com/wzhGitH/img ...
- jquery.chosen.js下拉选择框美化插件项目实例
由于之前使用的bootstrap-select插件是建立在bootstrap基础上的,实际使用到项目中的时候,与我们使用的ace-admin(基于bootstrap)存在样式冲突,导致下拉框的样式发生 ...
- [Vue]组件——实现动态组件:keep-alive的使用
1.在app.vue中用一个 <keep-alive> 元素将其动态组件包裹起来: keepAlive为true时,第一次被创建的时候缓存下来,为false时,不会缓存 <keep- ...
- Android系统源代码
Android系统源代码 在线源码网站 1,http://androidxref.com 2,http://www.grepcode.com/ 3,http://www.androidos.net.c ...