前言
kNN(k -Nearest Neighbours)算法是非常简单易懂的算法,它的适用范围很广,并且在样本量足够大的情况下获得很好的模型效果。它是一种用于分类和回归的非参数统计方法。
knn算法的理论和实战将会分为三个部分进行讲解,这是第一部分。
本部分具体内容如下:
- 讲解K-NN算法的基本概念、原理
- k的选取、特征归一化
一、 k近邻算法的基础
参考维基百科,我们给出以下解释:
- 在k-NN分类中,输出是一个分类族群。一个对象的分类是由其邻居的"多数表决"确定的,k个最近邻中最多的分类决定了被分类对象的类别。若K=1,则该对象的类别又它最近的一个节点赋予。也就是在分类中,我们在k值选定后,常常会采用少数服从多数的原则来确定待分类点的类别。
- 在k-NN回归中,输出是该对象的属性值。该值是其K个最近邻居的值的平均值。
knn用于分类和回归的大致方法基本相同,本文主要讲解用kNN进行分类。具体我们来看这么一张图(来自维基百科):
如上图所示,里面有红色三角形和蓝色正方形两类数据,现在来了一个未知的待分类点,我们需要判断它是属于哪一类。通过k近邻的思想,我们知道当k不同时,我们得到的结果是可能不同的。比如: - 当K=3时,绿色的圆形的最近邻三个点时1个蓝正方形、2个红三角形,按照少数服从多数原则,我们将这个待分类点分为红色三角形一类。
- 当K=5时,绿色的圆形的最近邻5个邻居时2个红三角形、3个蓝正方形,此时我们是将这个待分类点分为蓝色正方形一类。
通过以下的解释,我想大家心中肯定有一个疑问。在K选择的不同时,我们会对一个样本点得到不同的结论,但是实际生活中,一个样本肯定是有一个固定的类别的。那么,我们该如何去确定k值呢?
二、 K值的选取以及特征归一化的重要性
2.1 k值的选取
根据李航老师所讲的:
值的减小就意味着整体模型变的复杂,容易发生过拟合。k值的增大就意味着整体的模型变的简单。如果k=N,那么无论输入实例是什么,都将简单地预测它属于在训练实例中最多的类。这时,模型过于简单,完全忽略训练实例中的大量有用信息,是不可取的。在应用中,k值一般去一个比较小的数值。通常采用交叉验证法来选取最优的k值。
有一说一,上面这段话是真的有点绕啊。绕的让人头疼!!!
我们来看一下当我们取k=1的这个极端情况,为什么k=1能使模型变的复杂,又容易过拟合了呢?
上面仍然是有两类数据,黑色圆和蓝色矩形,红色五边形是我们要分类的点。我们现在通过以上数据点,在k=1时来对红色五边形进行分类。因为黑色圆与红色五边形距离最近,所以我们最终判定待分类点属于黑色圆点。
很明显,我们能够感觉到,红色五边形应该是属于蓝色长方形一类的。而我们知道,在实际的数据采集中,混入个别噪声是很普遍的。==当k=1时,模型就过于复杂,我们很容易学习到噪声,因此将待分类数据分类错误。==如果我们将k设置大一点,比如8,我们就很容易得到我们正确的分类应该是蓝色的长方形。
而根据李航老师所说,k越小模型越复杂,那么在k=1时,应该说模型时最复杂的。相反,k=样本个数时,模型是最简单的,这又是为什么呢?
我们可以这样来理解,在k=1时,通过刚刚举例时我们发现此时模型分类效果很容易受到噪声影响。所谓的过拟合,就是在训练集上准确率非常高,在测试集上准确率反而很低。正是因为我们模型在训练集上的学习能力太强了,连一些错误的噪声都能够学习到,所以我们认为它的模型是最复杂的,也是过拟合的。模型复杂代表着学习能力非常的强,模型能力非常强就容易产生过拟合的问题。
那么当我们选取较大的k值时,比如k=样本数,相当于是在整个样本训练集中进行预测,这个时候离待分类点很远的(完全不相似)的数据也会对该分类过程起到作用,从而会使预测发生错误。那么为什么说k值增大模型会变的十分简单呢?我们可以看到,k=样本个数后,我们所谓的训练就是在简单的预测训练集中类别最多的类!
仍然是这个图来举例子,这份训练集数据样本是有7个蓝色矩形,9个黑色圆形,如果k=样本数之后,那么无论是哪个待分类点,它都会被分类到黑色圆形中去。那么这样模型不就是非常简单了吗?我在一开始数好各个类别的数目,简单进行比较 7/16 < 9/16,然后整个模型就直接对分类点进行判断了。
因此,k值不能过大,也不能过小。就像在开头所说,具体应用中先选择一个较小的k值,然后进行交叉验证选取最优的k值。
2.2 特征归一化
在对样本进行训练时,特征的归一化也就是标准化是非常重要的。
举个例子,用一个人身高(cm)和脚码(尺码)大小来作为特征值,类别为男性或者女性。现有5个训练样本如下:
A [(179,42),男] B [(178,43),男] C [(165,36)女] D [(177,42),男] E [(160,35),女]。
通过样本,我们很容易看出,每个样本的第一维度的身高特征和第二维度的脚码特征相差太大了。我们在计算距离的时候(这里选用欧式距离),会偏向于第一维度的特征。也因此造成这两个特征对于模型的影响不是等价的,从而导致模型在分类时会有很大的偏差。
比如现在我们用测试样本F(167,43),来预测这个人是男性还是女性,选择k=3。通过欧式距离计算的结果如下:
计算可知,最近的前三个样本是C、D、E,C和E为女性,D为男性,所以我们预测样本F是女性。但是,根据常理可知,一个女性的脚43码的可能性,远小于男性脚43码的可能性,但是算法将F预测为女性是为什么?因为这两个特征的数值差距过大,导致身高的重要性远超过脚码,而我们应该让每个特征都同等重要。
因此,我们要标准化欧式距离:标准化欧氏距离是针对简单欧氏距离的缺点而作的一种改进方案。标准欧氏距离的思路:既然数据各维分量的分布不一样,那先将各个分量都“标准化”到均值、方差相等。至于均值和方差标准化到多少,先复习点统计学知识。
假设样本集X的数学期望或均值(mean)为m,标准差(standard deviation,方差开根)为s,那么X的“标准化变量”X*表示为:(X-m)/s,而且标准化变量的数学期望为0,方差为1。
即,样本集的标准化过程(standardization)用公式描述就是:
即,标准化后的值 = ( 标准化前的值 - 分量的均值 ) /分量的标准差。经过简单的推导就可以得到两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的标准化欧氏距离的公式:
如果我们将方差的倒数看作一个权重,这个公式可以看作是一种加权的欧式距离。
由于篇幅问题,我把实战部分放在了第二部分。第二部分代码实战请看:机器学习之K近邻(K-NN)算法 (二)