AI有道
一个有情怀的公众号
1
什么是k近邻算法?
k最近邻(k-Nearest Neighbor,kNN)分类算法是一个比较成熟也是最简单的机器学习(Machine Learning)算法之一。该方法的思路是:如果一个样本在特征空间中与k个实例最为相似(即特征空间中最邻近),那么这k个实例中大多数属于哪个类别,则该样本也属于这个类别。
其中,计算样本与其他实例的相似性一般采用距离衡量法。离得越近越相似,离得越远越不相似。
如上图所示,k=3,距离绿色样本最近的3个实例中(圆圈内),有两个是红色三角形(正类)、一个是蓝色正方形(负类)。则该样本属于红色三角形(正类)。
2
K近邻算法的本质
我们知道,一般机器学习算法包括两个过程:训练过程和测试过程。训练过程通过使用机器学习算法在训练样本上迭代训练,得到较好的机器学习模型;测试过程是使用测试数据来验证模型的好坏,通过正确率来呈现。kNN算法的本质是在训练过程中,它将所有训练样本的输入和输出标签(label)都存储起来。测试过程中,计算测试样本与每个训练样本的距离,选取与测试样本距离最近的前k个训练样本。然后对着k个训练样本的label进行投票,票数最多的那一类别即为测试样本所归类。
其实,kNN算法非常简单,可以说在训练过程中基本没有算法参与,只有存储训练样本。可以说KNN算法实际上是一种识记类算法。因此,kNN虽然简单,但是其明显包含了以下几个缺点:
整个训练过程需要将所有的训练样本极其输出label存储起来,因此,空间成本很大。
测试过程中,每个测试样本都需要与所有的训练样本进行比较,运行时间成本很大。
采用距离比较的方式,分类准确率不高。
好了,介绍完了kNN算法的理论知识之后,我相信大家都跃跃欲试了。接下来,我们就来手把手教大家使用Python实现一个kNN分类问题,进入机器学习实战大门。开始吧~
3
数据准备
首先,数据集我们选择经典的鸢尾花卉数据集(Iris)。Iris数据集每个样本x包含了花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)四个特征。样本标签y共有三类,分别是Setosa,Versicolor和Virginica。Iris数据集总共包含150个样本,每个类别由50个样本,整体构成一个150行5列的二维表,如下图展示了10个样本:
如何获取这些数据呢?很简单,我们可以使用代码,直接从网上下载,下载后的数据集存放在'../data/'目录下。
然后,我们将三个类别的数据分别提取出来,setosa、versicolor、virginica分别用0、1、2来表示。
接下来看一下三种类别不同特征的空间分布。为了可视性,我们只选择sepal length和petal length两个特征,在二维平面上作图。
由上图可见,三个类别之间是有较明显区别的。
接下来,我们要将每个类别的所有样本分成训练样本(training set)、验证集(validation set)和测试样本(test set),各占所有样本的比例分别为60%,20%,20%。
4
kNN训练函数和预测函数
kNN的训练过程实际上是一种数据标类、数据存储的过程,不包含机器学习算法。首先我们需要定义一个类(class)来实现KNN算法模块。该类的初始化定义为:
然后,在KNearestNeighbor类中定义训练函数,训练函数保存所有训练样本。
kNN的测试过程是核心部分。其中,有两点需要注意:
衡量距离的方式
k值的选择
kNN距离衡量一般有两种方式:L1距离和L2距离。
L1距离的计算公式为:
其中,I1和I2分别表示两个样本,p表示特征维度。
L2距离的计算公式为:
一般来说,L1距离和L2距离都比较常用。需要注意的是,如果两个样本距离越大,那么使用L2会继续扩大距离,即对距离大的情况惩罚性越大。反过来说,如果两个样本距离较小,那么使用L2会缩小距离,减小惩罚。也就是说,如果想要放大两个样本之间的不同,使用L2距离会更好一些。这里,我们使用最常用的L2距离。
kNN中的k值选择至关重要,不同的k值也许能归属到不同的类别中,例如在下图中,k=3,则判定绿色实例属于红色三角形类别。
但是,如果令k=5,如下图所示,则会判定绿色实例属于蓝色正方形类别。
一般来说,k值太小会使模型过于复杂,造成过拟合(overfitting);k值太大会使模型分类模糊,造成欠拟合(underfitting)。实际应用中,我们可以选择不同的k值,通过验证来决定K值大小。代码中,我们将k设定为可调参数。
在KNearestNeighbor类中定义预测函数:
KNearestNeighbor类的完整定义代码如下:
5
训练和预测
首先,创建一个KnearestNeighbor实例对象。
然后,在验证集上进行k-fold交叉验证。选择不同的k值,根据验证结果,选择最佳的k值。
可见,k值取3的时候,验证集的准确率最高。此例中,由于总体样本数据量不够多,所以验证结果并不明显。但是使用k-fold交叉验证来选择最佳k值是最常用的方法之一。
选择完合适的k值之后,就可以对测试集进行预测分析了。
最终结果显示,测试集预测准确率为100%。
最后,我们把预测结果绘图表示。仍然只选择sepal length和petal length两个特征,在二维平面上作图。
6
k近邻算法总结
k近邻算法是一种最简单最直观的分类算法。它的训练过程保留了所有样本的所有特征,把所有信息都记下来,没有经过处理和提取。而其它机器学习算法包括神经网络则是在训练过程中提取最重要、最有代表性的特征。在这一点上,kNN算法还非常不够“智能”。但是,kNN算法作为机器学习的基础算法,还是值得我们了解一下的。
领取专属 10元无门槛券
私享最新 技术干货