KNN算法理论

1.KNN算法简介
      K近邻法(k-nearest neighbor,KNN)是一种很基本的机器学习方法了,在我们平常的生活中也会不自主的应用,就是“物以类聚,人以群分”。比如,我们判断一个人的人品,只需要观察他来往最密切的几个人的人品好坏就可以得出了。这里就运用了KNN的思想。KNN方法既可以做分类,也可以做回归,这点和决策树算法相同。
      KNN做回归和分类的主要区别在于最后做预测时候的决策方式不同。KNN做分类预测时,一般是选择多数表决法,即训练集里和预测的样本特征最近的K个样本,预测为里面有最多类别数的类别。而KNN做回归时,一般是选择平均法,即最近的K个样本的样本输出的平均值作为回归预测值。由于两者区别不大,虽然本文主要是讲解KNN的分类方法,但思想对KNN的回归方法也适用。
2.KNN三要素
2.1k值的选择
      K值的选择会对k近邻法的结果产生重大影响。
      (1)如果选择较小的k值,就相当于用较小的邻域中的训练实例进行预测,“学习”的近似误差会减少,只有与输入实例较近的训练实例才会对预测结果起作用。但缺点是“学习”的估计误差会增大,预测的结果会对近邻的实例点非常敏感。如果近邻的实例点家好食噪声,预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易产生过拟合。
      (2)如果选择较大的k值,就相当于用较大的邻域中的训练实例进行预测,优点是可以减少估计误差,缺点是增大近似误差。这时与输入的实例较远的训练实例也会对预测起作用,使预测发生错误。k值的增大就意味着整体的模型变得简单。
      (3)如果k取样本数,那么无论输入实例是什么,都将简单地预测它属于在训练实例中的最多的类。这时,模型过于简单,完全忽略训练实例中的大量有用信息,是不可取的。
      在应用中,k值一般取一个较小的数值,通常采用交叉验证法来选择最优的k值
2.2距离的度量
      对于距离的度量我们有很多种方式,但是最常用的是欧氏距离,但也可是其他距离,如更一般的 距离或闵可夫斯基距离(Minkowski Distance),其距离定义为:
L p ( x i , x j ) = ( ∑ l = 1 n ∣ x i l − x j l ∣ p ) 1 p {{L}_{p}}\left( {{x}_{i}},{{x}_{j}} \right)={{\left( \sum\limits_{l=1}^{n}{{{\left| x_{i}^{l}-x_{j}^{l} \right|}^{p}}} \right)}^{\frac{1}{p}}} Lp(xi,xj)=(l=1nxilxjlp)p1
(1)欧式距离,即p=2
L 2 ( x i , x j ) = ( ∑ l = 1 n ∣ x i l − x j l ∣ 2 ) 1 2 {{L}_{2}}\left( {{x}_{i}},{{x}_{j}} \right)={{\left( \sum\limits_{l=1}^{n}{{{\left| x_{i}^{l}-x_{j}^{l} \right|}^{2}}} \right)}^{\frac{1}{2}}} L2(xi,xj)=(l=1nxilxjl2)21
(2)曼哈顿距离,即p=1
L 1 ( x i , x j ) = ( ∑ l = 1 n ∣ x i l − x j l ∣ ) {{L}_{1}}\left( {{x}_{i}},{{x}_{j}} \right)=\left( \sum\limits_{l=1}^{n}{\left| x_{i}^{l}-x_{j}^{l} \right|} \right) L1(xi,xj)=(l=1nxilxjl)
(3)p为无穷时,它是各个坐标距离的最大值
L ∞ ( x i , x j ) = max ⁡ l   ∣ x i l − x j l ∣ {{L}_{\infty }}\left( {{x}_{i}},{{x}_{j}} \right)=\underset{l}{\mathop{\max }}\,\left| x_{i}^{l}-x_{j}^{l} \right| L(xi,xj)=lmaxxilxjl
2.3分类决策规则
      k近邻法中的分类决策规则往往是多数表决,即输入实例的k个邻近的训练实例中的多数类决定输入实例的类。
      多数表决规则有如下解释:如果分类的损失函数为0-1损失函数,分类函数为:
f : R n → { c 1 , c 2 , . . . , c K } f:{{R}^{n}}\to \left\{ {{c}_{1}},{{c}_{2}},...,{{c}_{K}} \right\} f:Rn{c1,c2,...,cK}
      那么误分类的概率是:
P ( Y ≠ f ( X ) ) = 1 − ( Y = f ( X ) ) P\left( Y\ne f\left( X \right) \right)=1-\left( Y=f\left( X \right) \right) P(Y̸=f(X))=1(Y=f(X))
      对给定的实例x,其最近邻的k个训练实例点构成集合 N k ( x ) {{N}_{k}}\left( x \right) Nk(x)。如果涵盖 N k ( x ) {{N}_{k}}\left( x \right) Nk(x)的区域的类别是 c j {{c}_{j}} cj,那么误分类率是:
1 K ∑ x i ∈ N k ( x ) I ( y i ≠ c j ) = 1 − 1 K ∑ x i ∈ N k ( x ) I ( y i = c j ) \frac{1}{K}\sum\limits_{{{x}_{i}}\in {{N}_{k}}\left( x \right)}{I\left( {{y}_{i}}\ne {{c}_{j}} \right)}=1-\frac{1}{K}\sum\limits_{{{x}_{i}}\in {{N}_{k}}\left( x \right)}{I\left( {{y}_{i}}={{c}_{j}} \right)} K1xiNk(x)I(yi̸=cj)=1K1xiNk(x)I(yi=cj)
      要使得误分类率最小即经验风险最小,就要使 1 K ∑ x i ∈ N k ( x ) I ( y i = c j ) \frac{1}{K}\sum\limits_{{{x}_{i}}\in {{N}_{k}}\left( x \right)}{I\left( {{y}_{i}}={{c}_{j}} \right)} K1xiNk(x)I(yi=cj)最大,所以多数表决规则等价于经验风险最小化。
3.KNN暴力求解
      计算预测样本与所有训练集中的样本的距离,选出最小的k个距离所对应的样本,然后采用多数表决的方法进行预测。这个方法对于少量样本来说简单有效,但是对于大量样本来说效率太低。所以接下来介绍kd树和球树。
4.k近邻法的实现:kd树
      KNN中的k代表最近的k个样本,kd树中的k代表样本特征的维数。为了防止混淆,后面我们称特征维数为n。
4.1kd树的构造
      kd树是一种对k维空间中的十里店进行存储以便对其进行快速检索的树形数据结构。Kd树是二叉树,表示对k维的空间的一个划分。构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个节点相对应于k维超矩形区域。
      kd树建树采用的是从m个样本的n维特征中,分别计算n个特征的取值的方差,用方差最大的第k维特征 n k {{n}_{k}} nk来作为根节点。对于这个特征,我们选择特征 n k {{n}_{k}} nk的取值的中位数 n k v {{n}_{kv}} nkv对应的样本作为划分点,对于所有第k维特征的取值小于 的样本,我们划入左子树,对于第k维特征的取值大于等于 n k v {{n}_{kv}} nkv的样本,我们划入右子树,对于左子树和右子树,我们采用和刚才同样的办法来找方差最大的特征来做更节点,递归的生成kd树。
      具体的流程如下:
在这里插入图片描述
      例:给定一个二维空间的数据集: T = { ( 2 , 3 ) , ( 5 , 4 ) , ( 9 , 6 ) , ( 4 , 7 ) , ( 8 , 1 ) , ( 7 , 2 ) } T=\left\{ \left( 2,3 \right),\left( 5,4 \right),\left( 9,6 \right),\left( 4,7 \right),\left( 8,1 \right),\left( 7,2 \right) \right\} T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}构造一个平衡kd树。
      step1:找到划分的特征。6个数据点在x,y维度上的数据方差分别为6.97,5.37,所以在x轴上方差更大,用第1维特征建树。
      step2:确定划分点(7,2)。根据x维上的值将数据排序,6个数据的中值(所谓中值,即中间大小的值)为7,所以划分点的数据是(7,2)。这样,该节点的分割超平面就是通过(7,2)并垂直于:划分点维度的直线x=7;
      step3:确定左子空间和右子空间。 分割超平面x=7将整个空间分为两部分:x<=7的部分为左子空间,包含3个节点={(2,3),(5,4),(4,7)};另一部分为右子空间,包含2个节点={(9,6),(8,1)}。
      step4:用同样的办法划分左子树的节点{(2,3),(5,4),(4,7)}和右子树的节点{(9,6),(8,1)}。最终得到kd树。
在这里插入图片描述
在这里插入图片描述
4.2kd树的搜索
      当我们生成kd树以后,就可以去预测测试集里面的样本目标点了。预测的过程如下:
      输入:已构造的kd树;目标点x;
      输出:x的最近邻。
      step1:在kd树中找出包含目标点x的叶结点:从根结点出发,递归地向下访问kd树。若目标点x当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点。直到子结点为叶结点为止。
      step2:以此叶结点为“当前最近点”。
      step3:递归地向上回退,在每个结点进行以下操作:
      (a)如果该结点保存的实例点比当前最近点距离目标点更近,则以该实例点为“当前最近点”。
      (b)当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一子结点对应的区域是否有更近的点。具体地,检查另一子结点对应的区域是否与以目标点为球心、以目标点与“当前最近点”间的距离为半径的超球体相交。
如果相交,可能在另一个子结点对应的区域内存在距目标点更近的点,移动到另一个
子结点。接着,递归地进行最近邻搜索;如果不相交,向上回退。
      step4:当回退到根结点时,搜索结束。最后的“当前最近点”即为x的最近邻点。如果实例点是随机分布的,kd树搜索的平均计算复杂度是O(logN),这里N是训练实例数。kd树更适用于训练实例数远大于空间维数时的k近邻搜索。当空间维数接近训练实例数时,它的效率会迅速下降,几乎接近线性扫描。
      从上面的描述可以看出,kd树划分后可以大大减少无效的最近邻搜索,很多样本点由于所在的超矩形体和超球体不相交,根本不需要计算距离。大大节省了计算时间。
      例1:用4.1构建的kd树,来看对点(2,4.5)找最近邻的过程。
      step1:同样先进行二叉查找,先从(7,2)沿x维度查找到(5,4)节点,再沿着沿x维度进行查找,由y = 4为分割超平面的,由于查找点为y值为4.5,因此进入右子空间查找到(4,7),因为是叶节点,所以取(4,7)为当前最近邻点,计算其与目标查找点的距离为3.202。
      step2:然后回溯到(5,4),计算其与查找点之间的距离为3.041。由于距离相比(4,7)较小,因此(5,4)为查询点的当前最近邻点。
      step3:以(2,4.5)为圆心,以3.041为半径作圆,如下图所示。可见该圆和y = 4超平面交割,所以需要进入(5,4)左子空间进行查找。(注:此处不是说,上一步一旦回溯的父节点距离更小,被认为当前最近邻点后,就一定要去另一个子节点查找,这里的做圆并检测是否在当前分割维度交割是有必要的,举例来说,万一要检测的点是(5,4.1),这里就没交割,就不用去另一子空间查找。)
在这里插入图片描述
      step4:回溯至(2,3)叶子节点,(2,3)距离(2,4.5)比(5,4)要近,所以最近邻点更新为(2,3),最近距离更新为1.5。
      step5:回溯至(7,2),以(2,4.5)为圆心1.5为半径作圆,并不和x = 7分割超平面交割。至此,搜索路径回溯完。返回最近邻点(2,3),最近距离1.5。
      例2:给定一个如下图所示的kd树,根结点为A,其子结点为B,C等。树上共存储7个实例点;另有一个输入目标实例点S,求S的最近邻。 在这里插入图片描述
      :首先在kd树中找到包含点S的叶结点D(图中的右下区域),以点D作为近似最近邻。真正最近邻一定在以点S为中心通过点D的圆的内部。然后返回结点D的父结点B,在结点B的另一子结点F的区域内搜索最近邻。结点F的区域与圆不相交,不可能有最近邻点。继续返回上一级父结点A,在结点A的另一子结点C的区域内搜索最近邻。结点C的区域与圆相交;该区域在圆内的实例点有点E,点E比点D更近,成为新的最近邻近似。最后得到点E是点S的最近邻。
4.3kd树的预测
      有了kd树搜索最近邻的办法,kd树的预测就很简单了,在kd树搜索最近邻的基础上,我们选择到了第一个最近邻样本,就把它置为已选。在第二轮中,我们忽略置为已选的样本,重新选择最近邻,这样跑k次,就得到了目标的k个最近邻。然后根据多数表决法,如果是KNN分类,预测为k个最近邻里面有最多类别数的类别。如果是KNN回归,用k个最近邻样本输出的平均值作为回归预测值。
5. k近邻法的实现:球树
5.1球树的构建
      球树类似于kd树,球树的分割块是超球体。建树流程如下:
      step1:先构建一个超球体,这个超球体是可以包含所有样本的最小球体;
      step2:从球中选择一个离球的中心最远的点,然后选择第二个点离第一个点最远,将球中所有的点分配到离这两个聚类中心最近的一个上,然后就散每个聚类的中心,以及聚类能够包含它所有数据点所需的最小半径。这样我们得到了两个子超球体,和kd树里面的左右子树对应。
      step3:对于这两个子超球体,递归执行步骤2,最终得到了一个球树。
      可以看出kd树和球树类似,主要区别在于球树得到的是节点样本组成的最小超球体,而kd树得到的是节点样本组成的超矩形体,这个超球体要比对应的kd树的超矩形体小,这样在做最近邻搜索的时候,可以避免一些无谓的搜索。
5.2球树的搜索
      使用球树找出给定目标的最近邻方法是首选自上而下贯穿整棵树找出包含目标点所在的叶子,并在这个球里面找出与目标点最近邻的点,这将确定出目标点距离它的最近邻点的一个上限值,然后跟kd树查找一样,检查兄弟结点,如果目标点到兄弟结点中心的距离超过兄弟结点的半径与当前的上限值之和,那么兄弟结点里不可能存在一个更近的点,否则的话,必须进一步检查位于兄弟结点一下的子树。
      检查完兄弟结点后,我们向父结点回溯,继续搜索最近邻值。当回溯到根节点时,此时的最小近邻值就是最终的搜索结果。
      从上面的描述可以看出,kd树在搜索路径优化时使用的时候两点之间的距离来判断,而球树使用的是两边之和大于第三边来判断,相对来说球树的判断更加复杂,但是却避免了更多的搜索。
6.KNN的扩展
(1)限定半径最近邻算法
      样本中某系类别的样本非常的少,甚至少于K,这导致稀有类别样本在找K个最近邻的时候,会把距离其实较远的其他样本考虑进来,而导致预测不准确。为了解决这个问题,我们限定最近邻的一个最大距离,也就是说,我们只在一个距离范围内搜索所有的最近邻,这避免了上述问题。这个距离我们一般称为限定半径。
(2)最近质心算法
      它首先把样本按输出类别归类。对于第i类的Ci个样本。它会对这Ci个样本的n维特征中每一维特征求平均值,最终该类别所有维度的n个平均值形成所谓的质心点。对于样本中的所有出现的类别,每个类别会最终得到一个质心点。当我们做预测时,仅仅需要比较预测样本和这些质心的距离,最小的距离对于的质心类别即为预测的类别。这个算法通常用在文本分类处理上。
7.总结
7.1优点
(1)理论成熟,思想简单,既可以用来做分类也可以用来做回归;
(2)可用于非线性分类;
(3)训练时间复杂度比支持向量机之类的算法低,仅为O(n);
(4) 和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感;
(5)由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合;
(6)该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
7.2缺点
(1)计算量大,尤其是特征数非常多的时候;
(2)样本不平衡的时候,对稀有类别的预测准确率低;
(3)kd树,球树之类的模型建立需要大量的内存;
(4)使用懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢;
(5)相比决策树模型,KNN模型可解释性不强。

参考文章:
https://www.cnblogs.com/huangyc/p/9716079.html
https://www.cnblogs.com/CJT-blog/p/10124695.html
https://www.cnblogs.com/pinard/p/6061661.html
https://blog.csdn.net/zrh_CSDN/article/details/80956834

  • 3
    点赞
  • 80
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值