小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
🎞基本概念
k近邻(k-Nearest Neighbor,KNN)算法是一种基本分类和回归方法
k近邻算法,即是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分类到这个类中(类似于少数服从多数的思想)
- 如果k=3,绿色圆点的最邻近的3个点是2个红色小三角形和1个蓝色小正方形,少数服从多数,基于统计的方法,判定绿色的这个待分类点属于红色的三角形那一类。
- 如果k=5,绿色圆点的最邻近的5个邻居是2个红色三角形和3个蓝色正方形,还是少数服从多数,基于统计的方法,判定绿色的待分类点属于蓝色的正方形一类。
因此,从上面的例子可以看出,k近邻的算法核心思想是:给新来的点进行归类,只要找到离它最近的k个实例,哪个类别最多就属于哪一类。
🔈k值的选择
🚩k值过小
k值过小,会使整体模型变得复杂,容易发生过拟合。
所谓的过拟合就是在训练集上准确率非常高,而在测试集上准确率低。
假设我们有训练数据和待分类点如下图:
上图中有两类,一类是黑色的圆点,一类是蓝色的长方形,现在我们待分类的是红色的五边形。
当k=1时,很容易我们能够看出来五边形离黑色的圆点最近,那么根据k近邻算法的思想,我们最终判定待分类五边形属于黑色的圆点。
如果k太小了,我们很容易学习到噪声🙁,也就非常容易判定为噪声类别,而忽略了数据真实的分布。而在上图,如果k大一点,例如k=8,把蓝色长方形包括进来,我们很容易得到正确的分类应该是蓝色的长方形。
🚩k值过大
k值过大,会使与输入实例较远的(不相似的)训练实例也对预测起作用,导致预测错误,k值的增大意味着整体模型变得简单。
当k=n(n为训练样本的个数),那么无论输入实例是什么,都将简单地预测它属于在训练实例中最多的类。这时,模型变得非常简单,这相当于压根没有训练模型🙄,而直接拿训练数据统计了各个数据类别,然后找出最大的而已。
在上图例中,黑色圆点是9个,蓝色长方形是7个,若k=16(样本个数=9+7),那么根据k近邻算法思想,得出的结论是红色五边形属于黑色圆点,明显错误😅
这个时候,模型过于简单,完全忽略训练数据实例中大量有用信息,是不可取的。
k值既不能过大,也不能过小,我们k值的选择,在下图红色圆边界之间这个范围是最好的,如下图
😳在一般情况下,多维特征中,我们如何选取k值呢?
据李航博士书上讲到,我们一般选取一个较小的数值,通常采取交叉验证法来选取最优的k值。
交叉验证
交叉验证法的核心思想就是:把一些可能的k逐个去尝试,然后选出效果最好的k。
最常用的交叉验证是S折交叉验证,方法如下:
首先随机地将已给数据切分为S个互不相交、大小相同的子集,然后利用S-1个子集的数据训练模型,利用余下的子集测试模型,将这一过程对可能的S种选择重复进行,最后选出S次评测中平均测试误差最小的模型。
另一种常用方法是设置k等于训练集实例数量的平方根。
♠距离的度量
在上文中说到,k近邻算法是在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,我们就说预测点属于哪个类。
定义中所说的最邻近是如何度量的呢❓我们怎么知道谁跟测试点最邻近。这里就会引出几种距离度量的标准。
我们可以有以下几种度量方式:
在实际应用中,距离函数的选择应该根据数据的特性和分析的需要而定,由不同的距离度量所确定的最近邻点是不同的,一般选取p=2欧式距离表示。
♣ 特征归一化
首先举例如下,我用一个人身高(cm)与脚码(尺码)来作为特征值,类别为男性或者女性。现有5个训练样本,分布如下:
A[(172,42),男] B[(178,43),男] C[(165,36),女] D[(177,42),男] E[(160,35),女]
很容易看到第一维身高特征是第二维脚码特征的4倍左右,那么在进行距离度量时,我们就会偏向于第一维特征。这样造成两个特征不是同等重要的,最终可能会导致距离计算错误,从而导致预测错误。
例如现在有一个测试样本F(167,43),让我们来预测他是男性还是女性,我们采取k=3来预测。
下面我们用欧式距离分别计算出F离训练样本的欧式距离,然后取最近的3个,多数类别就是我们最终的结果,计算如下:
由计算可以得到,最近的前三个分别是C,D,E三个样本,那么由C,E为女性,D为男性,女性多于男性得到我们的预测结果为女性。
这样问题就来了,一个女性的脚43码的可能性,远远小于男性脚43码的可能性,那么为什么算法还是会预测F为女性呢?那是由于各个特征量纲的不同,在这里导致了身高的重要性已经远远大于脚码了,这是不客观的。所以,我们应该让每个特征都是同等重要的!
归一化公式如下:
📽分类决策规则
k近邻法中的分类决策规则往往是多数表决,即由输入实例的k个近邻的训练实例中的多数类决定输入实例的类。
多数表决规则有如下解释:
如果分类的损失函数为0-1损失函数,分类函数为:
那么误分类的概率是:
换句话说,目前候选种类为c1,c2,....cj,我选择哪一个能使得我们的经验风险最小(经验风险通俗讲就是训练数据的错误值)
📓小结
1️⃣ k近邻法是基本且简单的分类与回归方法。k近邻法的过程是:假如我们现在有一个数据集,当给定一个新的实例时,最简单粗暴的方法就是计算它和所有点的距离,然后找到k个最近邻,最后根据多数表决的规则判断这个实例所属的类。
2️⃣ k近邻模型对应于基于训练数据集对特征空间的一个划分。k近邻法中,当训练集、距离度量、k值及分类决策规则确定后,其结果唯一确定。
3️⃣ k近邻法三要素:距离度量、k值的选择和分类决策规则。常用的距离度量是欧式距离及更一般的Lp距离。k值小时,k近邻模型更复杂;k值大时,k近邻模型更简单。k值的选择反映了对近似误差与估计误差之间的权衡,通常由交叉验证选择最优的k。常用的分类决策规则是多数表决,对应于经验风险最小化。
💻代码示例
包括 knn算法简单示例、knn实现鸢尾花分类实例、构建kd树以及kd树搜索等,都在👉gitee.com/xin-yue-qin…👈
参考资料:一文搞懂k近邻(KNN)算法--忆臻