KNN原理及python实现(kd树)

  • 前面说的话

觉得自己完全看懂和做出来是两回事,希望自己可以坚持将机器学习算法基本都复现出来,并有时间进行时间空间复杂度的优化,用matlab梳理完思路后有时间再用python写一遍,毕竟我是一个厉害的小女子哈哈哈。
如果你阅读我的文章有什么疑问,或是任何学术讨论,欢迎和我交流:shitianqi1994@163.com


  • k近邻法原理

训练集是很多有特征有label的数据,当送进来一个没有label的数据需要判断时,选训练集中k个和这个数据最相似的数据,再将这k个数据的label以某种规则赋值给这个测试数据(比如规则为出现最多的label)。

这里的“相似“就是用距离进行度量。(欧式距离,曼哈顿距离等等)使用不同的距离确定的最近邻点是不同的,最后得到的label肯定也是不同的。

所以我们可以总结出,knn算法的三个基本要素是:

  1. k值的选取
  2. 距离的度量方式
  3. 分类决策规则

当这三个要素确定之后,模型完全确定,对于任何一个新的输入实例,它所属的类唯一确定。

k值的选择
k值的选取对knn的结果造成了较大的影响,如果k取的很小,那么只有和测试数据非常近的数据才能对结果产生影响,对近邻数据点非常敏感,但是如果此时近邻数据是噪声,那么就会造成过拟合。
也就是说,k值越小,建立的模型越复杂,越容易发生过拟合,k值越大,建立的模型越简单,即会选择性地丢掉一些信息,k值最大就是选取整个训练数据集中数据个数N,这时不管测试数据是什么都会被判定为训练数据集中最多label 的那个(假设决策规则是少数服从多数原则),这时的模型过于简单,完全没有考虑到值得考虑的因素。

在实际中,k一般取一个比较小的数值,通常采用交叉验证法来选取最优的k值。


  • k近邻法的实现:kd树

kd树的构建和搜索
这篇博文写的非常清楚。

  • 使用kd树结构完成knn算法matlab实现
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个简单的KD树KNN算法Python代码实现: ``` import numpy as np class KDTree: def __init__(self, data): self.k = data.shape[1] self.data = data self.left = None self.right = None self.split_dim = None self.split_value = None self.build() def build(self): if self.data.shape[0] == 0: return self.split_dim = np.argmax(np.var(self.data, axis=0)) self.split_value = np.median(self.data[:, self.split_dim]) left_data = self.data[self.data[:, self.split_dim] < self.split_value] right_data = self.data[self.data[:, self.split_dim] >= self.split_value] self.left = KDTree(left_data) self.right = KDTree(right_data) def search_knn(self, point, k): heap = [] self._search_knn(point, k, heap) return [h[1] for h in heap] def _search_knn(self, point, k, heap): if self.data is None: return dist = np.linalg.norm(point - self.data) if len(heap) < k: heap.append((dist, self.data)) heap.sort(key=lambda x: x[0]) elif dist < heap[-1][0]: heap[-1] = (dist, self.data) heap.sort(key=lambda x: x[0]) if self.left is None and self.right is None: return if point[self.split_dim] < self.split_value: self.left._search_knn(point, k, heap) if point[self.split_dim] + heap[-1][0] >= self.split_value: self.right._search_knn(point, k, heap) else: self.right._search_knn(point, k, heap) if point[self.split_dim] - heap[-1][0] < self.split_value: self.left._search_knn(point, k, heap) # 使用示例 data = np.random.rand(50, 2) tree = KDTree(data) point = np.array([0.5, 0.5]) k = 5 knn = tree.search_knn(point, k) print(knn) ``` 以上代码实现了一个简单的KD树KNN算法,可以用于查找数据集中与给定点最近的k个点。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值