java knn kd树_KD树实现KNN
最近在学习《统计学习方法》(李航著)。在第三章K近邻法中,先一如既往地从统计学习的三要素(模型、策略、算法)介绍了k近邻法,接着讲述k近邻法的一个具体实现方法-kd树,包括kd树的构造和kd树的搜索。
但是,在kd树搜索部分,书中只给出了使用kd树进行最近邻搜索(NNS)的算法描述,而使用kd树进行k近邻搜索的算法描述被留作课后习题。
对于本书第三章课后习题中3.3使用kd树进行k近邻搜索的算法及实现,网上鲜有描述(可能是太简单了o_O)。
本文尝试对此题借助优先队列进行解答:
算法(用kd树的k近邻搜索)
•输入:已构造的kd树;目标点x;k值;
•输出:x的最近邻
•算法过程:构造优先队列L(最大优先队列,距离从小到大的顺序排队)
在树中找出包含目标点x的叶结点:从根结点递归访问kd树,若x当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点,直到子结点为叶结点
将此节点插入队列L,如果L长度大于k,则获取并删除队首元素
递归地向上回退,在每个结点进行以下操作
(a) 如果该结点保存的实例点比L队首更近,则将此节点插入队列L,如果L长度大于k,则获取并删除队首元素
(b) 检查该子结点的父结点的另一子结点对应的区域是否有比L队首更近的点。
具体地,检查另一子结点对应的区域是否与以“L队首结点”为球心、以目标点与“L队首结点”间的距离为半径的超球体相交
如果相交,可能在另一个子结点对应的区域内存在距离“L队首结点”更近的点,移动到另一个子结点.递归地进行k近邻搜索
如果不相交,向上回退
5. 当回退到根结点时,搜索结束,最后的L队列中的结点即为x的k近邻点
算法实现(python)
kd树结点表示为如下:
class KdNode(object):
def __init__(self):
self.element = None
self.split_dim = None
self.left = None
self.right = None
构建kd树
def construct_tree(X_train):
def construct(X_train, indices, depth):
split_dim = depth % X_train.shape[1]
cur_node = KdNode()
zipped_indices = list(zip(X_train[indices, split_dim], indices))
updated_array= median(zipped_indices)
cur_node.element = updated_array[len(indices) // 2][1]
cur_node.split_dim = split_dim
if len(indices) > 1:
left_indices = list(map(lambda x: x[1], updated_array[:len(indices) // 2]))
cur_node.left = construct(X_train, left_indices, depth + 1)
if len(indices) > 2:
right_indices = list(map(lambda x: x[1], updated_array[len(indices) // 2 + 1:]))
cur_node.right = construct(X_train, right_indices, depth + 1)
return cur_node
return construct(X_train, np.arange(X_train.shape[0]), 0)
kd树搜索k近邻(KNN类的方法)
def search_kdt(self, tree, data, queue):
if tree is None:
return
if data[tree.split_dim] <= self.X_train[tree.element,tree.split_dim]:
self.search_kdt(tree.left, data, queue)
else:
self.search_kdt(tree.right, data, queue)
queue.put((distance(self.X_train[tree.element,:], data, p = self.p), tree.element))
if queue.size() > self.n:
queue.get()
# check another child
max_in_k = queue.first()
axis_distance = abs(data[tree.split_dim] - self.X_train[tree.element, tree.split_dim])
if max_in_k[0] > axis_distance:
if data[tree.split_dim] <= self.X_train[tree.element, tree.split_dim]:
self.search_kdt(tree.right, data, queue)
else:
self.search_kdt(tree.left, data, queue)
KNN模型如下(PriorityQueue为优先队列,篇幅有限,不列出具体实现)
'''KNN model with kdtree'''
class KNN:
def __init__(self, n_neighbors=3, p=2):
"""parameter: n_neighbors 临近点个数parameter: p 距离度量"""
self.n = n_neighbors
self.p = p
self.X_train = None
self.y_train = None
self.kdt_root = None
def fit(self, X, Y):
self.X_train = X
self.y_train = Y
self.kdt_root = construct_tree(self.X_train)
def predict(self, X):
if self.X_train is None or self.y_train is None:
print("Model has not been trained before prediction")
return None
ret = np.zeros((X.shape[0]))
# 取出top n个点
features_set = set(self.y_train)
Y_features = len(features_set)
for i in range(X.shape[0]):
queue = PriorityQueue(op=lambda x, y: x[0] > y[0])
self.search_kdt(self.kdt_root, X[i, :], queue)
# k个近邻多数表决
counter = {}
for each_feature in features_set:
counter[each_feature] = 0
for each_index in queue.data():
counter[self.y_train[each_index[1]]] += 1
ret[i] = max(counter, key=counter.get)
return ret
java knn kd树_KD树实现KNN相关推荐
- java knn kd树_KNN算法之KD树(K-dimension Tree)实现 K近邻查询
KD树是一种分割k维数据空间的数据结构,主要应用于多维空间关键数据的搜索,如范围搜索和最近邻搜索. KD树使用了分治的思想,对比二叉搜索树(BST),KD树解决的是多维空间内的最近点(K近点)问题.( ...
- [Leedcode][JAVA][第820题][字典树][Set]
[问题描述] 给定一个单词列表,我们将这个列表编码成一个索引字符串 S 与一个索引列表 A.例如,如果这个列表是 ["time", "me", "be ...
- java二叉树是什么_树的基本概念以及java实现二叉树
树具有的特点有: (1)每个结点有零个或多个子结点 (2)没有父节点的结点称为根节点 (3)每一个非根结点有且只有一个父节点 (4)除了根结点外,每个子结点可以分为多个不相交的子树. 树的基本术语有: ...
- java树_Java树
树(tree)是一种抽象数据类型(ADT),用来模拟具有树状结构性质的数据集合.它是由n(n>0)个有限节点通过连接它们的边组成一个具有层次关系的集合.把它叫做"树"是因为它 ...
- java工具:字典树(单词查找树/Trie树)的实现以及使用
项目地址 https://github.com/kylin-hunter/k-dic 文章目录 项目地址 前言 一.字典树 二.使用步骤 1 引入库 1.1 编译并发布到本地 1.2 gradle ( ...
- KNN算法(二) sklearn KNN实践
上次介绍了KNN的基本原理,以及KNN的几个窍门,这次就来用sklearn实践一下KNN算法. 一.Skelarn KNN参数概述 要使用sklearnKNN算法进行分类,我们需要先了解sklearn ...
- Trie(前缀树/字典树)及其应用
from:https://www.cnblogs.com/justinh/p/7716421.html Trie,又经常叫前缀树,字典树等等.它有很多变种,如后缀树,Radix Tree/Trie,P ...
- 数据结构 多路查找树 ---------B树和B+树的简单介绍
参考链接:微信公众号 程序员小灰 https://mp.weixin.qq.com/s/rDCEFzoKHIjyHfI_bsz5Rw https://mp.weixin.qq.com/s/jRZMMO ...
- hdu 4836 The Query on the Tree(线段树or树状数组)
The Query on the Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- 二叉树 红黑树 B树 B+树的优缺点
前言 在MySQL中,无论是Innodb还是MyIsam,都使用了B+树作索引结构(这里不考虑hash等其他索引).本文将从最普通的二叉查找树开始,逐步说明各种树解决的问题以及面临的新问题,从而说明M ...
最新文章
- 漫谈我国主流人工智能软件基础设施
- JAVA enum实现简单状态机功能
- 浙江万里学院计算机专业宿舍,浙江万里学院宿舍条件,宿舍几人间环境好不好(图片)...
- 转载 oracle12c 切换字符集
- 在 SAP 电商云 Spartacus UI 里使用自定义配置控制 UI 调试的开关
- 服务器程序的Xamarin-Java.Interop体验(一)
- oracle 11g新特性之IPS Packing demonstration
- Google的21道面试问题
- c# json 汉字乱码_C# 读取Json内的数据,中文乱码,怎么解决
- 相机标定原理介绍(一)
- 好用的源码行数统计工具——cloc
- mysql测评作业指导书_测评作业指导书
- Mahony 互补滤波
- 河北农业大学林学可转计算机系吗,河北农业大学专业排名,招生专业目录(10篇)...
- python 开发个人日常操作笔记
- Linux文件名包含小括号处理
- Android10power有哪些功能,Android 功耗(10)---电流波形图(power monitor)
- 基于Matlab的车牌识别系统完整版课论文分享 快看
- X86/X64汇编语言基础
- C++之一些事一些情--写在前面
热门文章
- webRTC初探:如何实现音视频的录制
- STAMP:扩增子、宏基因组统计分析神器(中文帮助文档)
- 正宗eMule官方网站导航
- 大型体检系统源码,PEIS医院体检管理系统源码
- 前端表白Html+css+js,表白源码,520和七夕告白,雪花爱心记录
- Word 电子签名简单制作方法
- 搜索不到投屏设备怎么办_投屏,搜索不到电视设备解决方案
- ae中合成设置的快捷键_提升AE效率的20个快捷键
- 1. 测度论-概率空间的基本概念
- 图算法(十一):紧密中心度算法(Closeness Centrality)【适用场景:社交网络中关键节点发掘】【计算一个节点到所有其他可达节点的最短距离的倒数再累积归一化】【值越大,节点越靠近图中心】