概述
k近邻法(k-nearest neighbor, k-NN)是一种基本分类与回归方法(此处讨论的是分类问题的K近邻算法)。
k近邻法实际上利用训练数据集对特征向量空间进行划分,并作为其分类的“模型”,不具有显式的学习过程。
k近邻算法的特殊情况是k=1的时候,此时称为最近邻算法。
k值的选择、距离度量及分类决策规则是k近邻法的三个基本要素。
K近邻算法
k近邻模型
1、模型
在k近邻算法中,当训练集、最近邻值k、距离度量、决策规则等确定下来时,整个算法实际上是利用训练集把特征空间划分成一个个子空间,训练集中的每个样本占据一部分空间。
具体地,在特征空间中,对每个训练样本而言,距离该点比其他点更近的所有点组成一个区域,叫做单元。每个训练样本拥有一个单元,所有样本的单元构成对特征空间的一个划分。然后该单元的所有点的标签都和该单元的样本点一致。
以最近邻为例,当测试样本落在某个训练样本的领域内,就把测试样本标记为这一类。
2、距离度量
特征空间中两个实例点的距离是两个实例点相似程度的反映。
常用的是欧氏距离,也可以是其他距离。
值得注意的是,使用不同的距离度量,计算出的最近邻点是不同的。
更多距离度量详见该博客:https://blog.csdn.net/h_wlyfw/article/details/24023325
3、k值的选择
如果选择较小的k值,“学习”的近似误差( approximation ertor)会减小,只有与输入实例较近的(相似的)训练实例才会对预测结果起作用。但缺点是“学习”的估计误差(estimarion ertor)会增大,预测结果会对近邻的实例点非常敏感。如果邻近的实例点恰巧是噪声, 预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合。
4、分类决策规则
k近邻法的实现:kd树
考虑这样的问题, 给定一个数据集D和某个点x,找出与x距离最近的k个点。这是一类很常见的问题,最简单的方法是暴力搜索,直接线性搜索所有数据,直到找到这k个点为止。对少量数据而言,这种方法还不错,但对大量、高纬度的数据集来说,这种方法的效率就差了。我们知道,排序好的数据查找起来效率很高,所以,可以利用某种规则把已有的数据“排列”起来,再按某种特定的搜索算法,以达到高效搜索的目的。“kd树”这是这样一种方法。
1、构造kd树
注:选择坐标的中位数(不是该轴中间点,是排序后的中间值)作为切分点事为了得到平衡的kd树,但是平衡kd树搜索时的效率未必是最优的。另外,mod是取余操作。
即
2、搜索kd树
一个具体例子:利用刚才构建好的kd树查找点为(2,4.5)
1、同样先进行二叉查找,先从(7,2)沿沿x0维度查找到(5,4)节点,再沿着沿x1维度进行查找,由y = 4为分割超平面的,由于查找点为y值为4.5,因此进入右子空间查找到(4,7),因为是叶节点,所以取(4,7)为当前最近邻点,计算其与目标查找点的距离为3.202。
2、然后回溯到(5,4),计算其与查找点之间的距离为3.041。由于距离相比(4,7)较小,因此(5,4)为查询点的当前最近邻点。
3、以(2,4.5)为圆心,以3.041为半径作圆,如下图所示。可见该圆和y = 4超平面交割,所以需要进入(5,4)左子空间进行查找。(注:此处不是说,上一步一旦回溯的父节点距离更小,被认为当前最近邻点后,就一定要去另一个子节点查找,这里的做圆并检测是否在当前分割维度交割是有必要的,举例来说,万一要检测的点事(5,4.1),这里就没交割,就不用去另一子空间查找。)
4、回溯至(2,3)叶子节点,(2,3)距离(2,4.5)比(5,4)要近,所以最近邻点更新为(2,3),最近距离更新为1.5。
5、回溯至(7,2),以(2,4.5)为圆心1.5为半径作圆,并不和x = 7分割超平面交割,如下图所示。
6、至此,搜索路径回溯完。返回最近邻点(2,3),最近距离1.5。
(该文应补代码的,等我仿完数据结构那本书就来补,暂时参考:https://blog.csdn.net/dobests/article/details/48580899)
来源:https://www.cnblogs.com/CJT-blog/p/10124695.html