经典机器学习算法:K邻近算法

前言

  对于与机器学习,笔者的认识是,他在模仿人类大脑的思考方式,人类大脑几乎做的所有事情都是判断一个东西是什么,这个东西能干吗,判断一个东西是什么,这是典型的分类问题,是根据自己从小到大接触到的事物进行判断,眼前的物体是一个什么东西,训练数据就是自己见过的所有东西,大脑对输入数据进行分类,这就类比于机器学习中的分类问题;这个东西能干嘛,是根据自己曾经的所有的生活经验去判断一个东西的功能,可以说是一种预测行为,也就是机器学习中的回归问题。因此将机器学习大致的分为回归问题分类问题是非常合理的,当然实际上很多方面要具体区分是哪类问题可能会不太清晰。
  本篇文章中,笔者将介绍经典机器学习算法中的K邻近算法。

1.什么是K邻近算法

  对于一个样本上的每一个数据,都在训练集上分别搜索K个最相近的数据。对于回归问题,这可能是求k个数据的平均数据作为输出量,对于分类问题,输出量可能是一个类。
  笔者从事的视觉方面的研究,所以对于笔者来说,K邻近算法可以暴力解决两张图片的特征点匹配问题,将一张图片中的某个特征点的描述子(高维特征向量)与另一幅图片中的所有描述子求取“距离”,选取一个最近的描述子,该描述子所代表的特征点就匹配点,这应该算是最简单的k=1的邻近算法,这个距离有很多种度量方式, 欧氏距离用的是比较多的。




L-P范数
在这里插入图片描述

曼哈顿距离——对应L1范数
曼哈顿距离对应L1范数,也就是在欧几里得空间的固定直角坐标系上两点所形成的线段对轴产生的投影的距离总和。
在这里插入图片描述
欧氏距离——对应L2范数
最常见的两点之间或多点之间的距离表示法,又称之为欧几里得度量,它定义于欧几里得空间中
在这里插入图片描述

K邻近算法的优缺点
优点

  1. 理论成熟,思想简单,既可以用来做分类也可以用来做回归;
  2. 可用于非线性分类;
  3. 对数据没有假设,准确度高,对outlier不敏感;
  4. KNN是一种在线技术,新数据可以直接加入数据集而不必进行重新训练;
  5. KNN理论简单,容易实现;

缺点

  1. 样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少)效果差;
  2. 需要大量内存;
  3. 对于样本容量大的数据集计算量比较大(体现在距离计算上);
  4. 样本不平衡时,预测偏差比较大。如:某一类的样本比较少,而其它类样本比较多;
  5. KNN每一次分类都会重新进行一次全局运算;
  6. k值大小的选择没有理论选择最优,往往是结合K-折交叉验证得到最优k值选择;

2.K邻近算法的改进(k-d tree)

  k-d tree是每个节点均为k维数值点的二叉树,其上的每个节点代表一个超平面,该超平面垂直于当前划分维度的坐标轴,并在该维度上将空间划分为两部分,一部分在其左子树,另一部分在其右子树。即若当前节点的划分维度为d,其左子树上所有点在d维的坐标值均小于当前值,右子树上所有点在d维的坐标值均大于等于当前值。k-d tree是一种数据结构。
  举例:将(7,2),(5,4),(2,3),(4,7),(9,6),(8,1)划分为k-d tree结构,如下图(参考了https://zhuanlan.zhihu.com/p/112246942):
在这里插入图片描述
构建步骤:

1、初始化分割轴:发现x轴的方差较大,所以,最开始的分割轴为x轴。

2、确定当前节点:对{2,5,9,4,8,7}找中位数,发现{5,7}都可以,这里我们选择7,也就是(7,2);

3、划分双支数据:在x轴维度上,比较和7的大小,进行划分:左支:{(2,3),(5,4),(4,7)}右支:{(9,6),(8,1)}

4、更新分割轴:方差较大的为分割轴

5、确定子节点:左节点:在左支中找到y轴的中位数(5,4),左支数据更新为{(2,3)},右支数据更新为{(4,7)},右节点:在右支中找到y轴的中位数(9,6),左支数据更新为{(8,1)},右支数据为null。

6、更新分割轴:方差较大的为分割轴

7、确定(5,4)的子节点:左节点:由于只有一个数据,所以,左节点为(2,3),右节点:由于只有一个数据,所以,右节点为(4,7)

8、确定(9,6)的子节点:左节点:由于只有一个数据,所以,左节点为(8,1),右节点:右节点为空。

最终,就可以构建整个的kd-tree了。


  在构建了完整的kd-tree之后,可以使用他来进行高维空间的检索。

一个最近邻
只需要定位到对应的分支上,找到最接近的点就可以了,比如查找(2.1,3.1)的最近邻。

1、计算当前节点(7,2)的距离,为6.23,并且暂定为(7,2),根据当前分割轴的维度(2.1 < 7),选取左支。
2、计算当前节点(5,4)的距离,为3.03,由于3.03 < 6.23,暂定为(5,4),根据当前分割轴维度(3.1 < 4),选取左支。
3、计算当前节点(2,3)的距离,为0.14,由于0.14 < 3.03,暂定为(2,3),根据当前分割轴维度(2.1 > 2),选取右支,而右支为空,回溯上一个节点。
4、计算(2.1,3.1)与(5,4)的分割轴{y = 4}的距离,如果0.14小于距离值,说明就是最近值。如果大于距离值,说明,还有可能存在值与(2.1,3.1)最近,需要往右支检索。
由于0.14 < 0.9,我们找到了最近邻的值为(2,3),最近距离为0.14。

多个最近邻
参考这里https://www.joinquant.com/view/community/detail/c2c41c79657cebf8cd871b44ce4f5d97,讲得非常的详细

3.总结

  在k-d tree的数据结构上进行KNN算法在计算效率上大大提升,否则要对每一个数据都进行比较是非常耗时的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值