赞
踩
当有多种类别数据时,我们常常面临着将新加入的数据进行分门别类的问题。比如根据口味色泽划分新的葡萄酒的类别,根据内容形式划分新上映电影的类别,根据过往人脸特征进行人脸识别。我们可以采用机器学习中非常经典的K近邻算法来解决这些问题,这一章节将讲解K近邻分类算法的原理和代码实现,同时将介绍手写数字识别模型的案例来巩固所学知识点。
K近邻算法 (K-Nearest Neighbor, 也简称KNN算法) 是非常经典的机器学习算法,这一节主要介绍一下K近邻算法的基本原理,并通过简单案例来讲解如何通过Python来实现K近邻算法。
K近邻算法的原理非常简单:对于一个新的数据而言,K近邻算法的目的就是在已有数据中寻找与它最相似的K个数据,或者说“离它最近”的K个数据,如果这K个点大多数属于某一个类别,则该样本也属于这个类别。
以上图为例,假设五角星和三角形分别代表两类不同的电影,一类是爱情片,一类是动作片。此时加入一个新样本正方形,此时需要判断该电影的类别。当选择以离新样本最近的3个近邻点时(K=3)为判断依据时,这3个点由1个五角星和2个三角形组成,由少数服从多数原则,可以认为新样本属于三角形的类别,即新样本是一部动作片。同理,当选择离新样本最近的5个近邻点时(K=5)为判断依据时,离新样本最近的5个点由3个五角星和2个三角形组成,由少数服从多数原则,认为新样本属于五角星的类别,即新样本是一部爱情片。
明白了K的含义后,我们来解释下如何来判断两个数据的相似度,或者说两个数据的距离,这里采用最为常见欧氏距离来定义向量空间内2个点的距离,对于二维空间而言,样本A的两个特征值为(X1,Y1),而样本B的两个特征值为(X2,Y2),那么两个样本的距离公式如下:
这个其实就是常见的两点间距离公式,如下图所示,其适合于特征变量只有两个的情况下。
实际应用中,数据的特征通常有n个,此时可将该距离公式推广到n维空间,如n维向量空间下A点坐标为(X1,X2,X3,…Xn),B点坐标为(Y1,Y2,Y3,…,Yn),那么A、B两点间的欧氏距离为:
在讲解如何利用代码实现之前,我们先用一个简单的数学案例讲解下kNN算法的步骤。
1.读取数据
这里以一个简单的例子来讲解一下K近邻算法的基本原理:如何判断葡萄酒的种类。为方便演示,我们只选取了2个特征变量来对葡萄酒进行分类,实际生活中,用来评判葡萄酒的指标要多得多。此处假设可以根据酒精含量和苹果酸含量将葡萄酒分为2类。
import pandas as pd
df = pd.read_excel('葡萄酒.xlsx')
此时的df如下表所示,为方便演示,该数据集只有5个原始样本数据。
其中酒精含量代表葡萄酒中酒精的含量高低,苹果酸含量代表葡萄酒中苹果酸的含量高低,分类取值为0代表葡萄酒A,分类取值为1代表葡萄酒B。
现在需要使用K近邻算法对一个新样本进行分类,该新样本的特征数据如下所示,那么这个新样本是属于葡萄酒A呢,还是属于葡萄酒B呢?
2.计算距离
此时我们可以利用距离公式来计算新样本与已有样本之间的距离,也即不同样本间的相似度,例如我们可以计算新样本与样本1的距离,公式如下:
同理可以计算新样本与其他原始样本的距离,如下表所示:
3.根据K值判定类别
获得了各个原始样本与新样本的距离后,我们就可以将其根据距离由近到远进行排序,如下表所示:
此时如果令K值等于1,也就是以离新样本距离最近的原始样本的种类作为新样本的种类,那么新样本离样本2最近,那么新样本的分类为0,也就是葡萄酒A。
如果令K值等于2,虽然有两个分类,但是它会优先选择2个分类结果中离它最近的那个。
如果令K值等于3,那么就是以离新样本最近的3个原始样本的多数样本的种类为判断依据,此时最近的3个原始样本是样本2、样本1、样本4,它们中以分类0居多,所以判定新样本的分类为0,也就是葡萄酒A。
4.K近邻算法的代码实现
上面讲解了K近邻算法基本运算步骤,而其实这些运算步骤在Python中已经有相关的库给封装好了,直接进行调用即可。
首先把原始数据进行特征变量和目标变量的切分从而方便之后进行模型的训练,代码如下:
X_train = df[['酒精含量(%)','苹果酸含量(%)']]
y_train = df['分类']
然后就可以直接调用Python已经开发好的相关库来进行K进邻算法的运算了,代码如下:
from sklearn.neighbors import KNeighborsClassifier as KNN
knn = KNN(n_neighbors=3)
knn.fit(X_train, y_train)
其中第一行代码为引用的Scikit-Learn库中的KNN模型;第二行代码设置KNN模型中的临近参数n_neighbors,也就是上面提到过的K值,这里设置其值为3,也就选取最近的三个样本,如果不设置的话则取默认值5;第三行代码就是进行模型训练了。
模型训练完之后就可以来进行预测了,代码如下:
X_test = [[7, 1]] # X_test为测试集特征变量
answer = knn.predict(X_test)
第一行代码中的X_test就是新样本的特征变量:7%的酒精含量及1%的苹果酸含量,注意这里要写成二维数组的形式,不然模型会报错;第二行就是对目标变量进行预测了,得到的是一个一维数组,此时得到的预测结果answer如下所示,和之前通过数学运算的方法获得结果一致。
[0]
感兴趣的读者可以在测试数据中再传入一个新样本,比如我们传入一个和样本4(类别1)一样的样本(8%的酒精度,3%的苹果酸含量),代码如下:
X_test = [[7, 1], [8, 3]] # 这里能帮助理解为什么要写成二维数组的样式
answer = knn.predict(X_test)
此时得到的预测结果answer如下所示,可以看到第二个和样本4一样的新样本的确被预测为和样本4一样的类别,也即类别1了。
[0 1]
补充知识点:K近邻算法回归模型
K近邻算法除了可以做分类分析,也可以做回归分析,分别对应的模型为K近邻算法分类模型(KNeighborsClassifier)及K近邻算法回归模型(KNeighborsRegressor)。
KNeighborsClassifier将待预测样本点最近邻的k个训练样本点中出现次数最多的分类作为待预测样本点的分类;
KNeighborsRegressor将待预测样本点最近邻的k个训练样本点的平均值作为待预测样本点的回归值。
K近邻算法回归模型的引入方式:
from sklearn.neighbors import KNeighborsRegressor
在Jupyter Notebook编辑器中,在引入该库后,可以通过如下代码获取官方讲解内容:
KNeighborsRegressor?
K近邻算法回归模型简单代码演示如下所示:
from sklearn.neighbors import KNeighborsRegressor
X = [[1, 2], [3, 4], [5
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。