一、KNN算法的基本概念和特点
KNN算法是一种基于最近邻的分类和回归方法。它的基本思想是,给定一个待分类的样本,根据它与已知类别的训练样本之间的距离,找出最近的K个邻居,然后根据这些邻居的类别进行多数表决或加权表决,从而确定样本的类别。
KNN算法有以下几个特点:
1、KNN算法是一种无参数的方法,即不需要假设数据服从某种特定的分布或者确定模型参数。
2、KNN算法是一种惰性的方法,即不需要在训练阶段进行显式的学习,而是在预测阶段才进行计算。
3、KNN算法是一种非线性的方法,即可以处理非线性可分的数据,但也可能受到噪声和异常值的影响。
4、KNN算法的关键因素有两个:距离度量和K值选择。距离度量决定了样本之间的相似性,常用的有欧式距离、曼哈顿距离、闵可夫斯基距离等。K值选择决定了邻居的数量,通常通过交叉验证来确定最优的K值。
二、KNN算法的原理
①、距离度量
距离度量是用来计算样本之间的相似性或者差异性的方法。不同的距离度量会导致不同的分类结果。常用的距离度量有以下几种:
欧式距离:欧式距离是最常用的距离度量,它是根据勾股定理计算两个点之间的直线距离。欧式距离的数学公式如下:
其中,x和y是两个n维向量,xi和yi是它们的第i个分量。欧式距离可以反映样本之间的绝对差异,但是它也受到数据尺度的影响,因此需要对数据进行归一化处理。欧式距离的一个示例是:如果有两个样本x=(1,2)和y=(3,4),那么它们之间的欧式距离为√(1-3)²+(2-4)²=√8
曼哈顿距离:曼哈顿距离是根据城市街区的距离计算两个点之间的最短路径。曼哈顿距离的数学公式是:
其中,x和y是两个n维向量,xi和yi是它们的第i个分量。曼哈顿距离可以反映样本之间的相对差异,但是它也受到数据尺度的影响,因此需要对数据进行归一化处理。曼哈顿距离的一个示例是:如果有两个样本x=(1,2)和y=(3,4),那么它们之间的曼哈顿距离是d(x,y)= |1-3| + |2-4| =4
②K值选择
k值选择是指确定最近邻的数量的方法。k值的大小会影响分类的准确性和复杂性。k值过小,会导致分类结果受到噪声和异常值的干扰,造成过拟合;k值过大,会导致分类结果受到较远样本的影响,造成欠拟合。
通常,k值的选择需要根据数据的分布和特征来确定,一种常用的方法是通过交叉验证来评估不同的k值对分类性能的影响,然后选择最优的k值。交叉验证的原理是将数据集分为训练集和测试集,然后在训练集上进行模型训练,在测试集上进行模型评估,重复多次并取平均值,从而得到不同k值下的分类准确率 。
③分类决策规则
分类决策规则是指根据最近邻的类别来确定待分类样本的类别的方法。最常用的分类决策规则是多数表决,即选择最近邻中出现次数最多的类别作为待分类样本的类别。多数表决的优点是简单易实现,但是它也有一些缺点,如不能反映邻居之间的距离差异,也不能处理类别平衡问题。
为了解决这些问题,一种改进的方法是加权表决,即根据邻居与待分类样本之间的距离来给邻居赋予不同的权重,然后选择权重之和最大的类别作为待分类样本的类别。加权表决的优点是可以考虑邻居之间的距离差异,也可以处理类别平衡问题,但是它也需要确定合适的权重函数 。
三、算法实现
# 导入模块
from sklearn.datasets import load_digits[^1^][1]
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
# 加载数据集
digits = load_digits()
x_data = digits.data
y_data = digits.target
# 划分训练集和测试集
x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.2)
# 创建KNN对象
knn = KNeighborsClassifier(n_neighbors=5)
# 训练模型
knn.fit(x_train, y_train)
# 预测结果
y_predict = knn.predict(x_test)
# 计算准确率
percent = knn.score(x_test,y_test)
#输出准确率
print(percent)
主要步骤如下:
1.导入需要的模块sklearn.datasets, sklearn.model_selection, sklearn.neighbors, numpy等。
2.加载MNIST数据集,这是一个包含了1797个0-9的手写数字图像的数据集,每个数字由8x8大小的矩阵构成,矩阵中值的范围是0-16,代表颜色的深度 。
3.划分训练集和测试集,使用train_test_split函数,设置test_size为0.2,表示测试集占总数据的20%。
4.创建一个KNeighborsClassifier对象,设置n_neighbors为5,表示选择最近的5个邻居进行分类。
5.使用fit方法在训练集上训练模型,使用predict方法在测试集上进行预测,得到预测结果y_predict。
6.使用score方法计算模型在测试集上的准确率percent,并输出正确率
运行结果如下:
修改k值为10再次运行,结果如下:
四、总结
knn算法作为比较简单的一种算法,有他的优点和局限性。knn算法的优点在于简单易实现,无需训练和参数估计,只需要存储训练数据即可,并且可以处理多分类问题,处理非线性可分的数据,以及可以动态更新训练数据,以适应新的样本和类别。
但knn算法也有诸如计算量大、存储空间大、对噪声和异常值敏感,需要进行数据清洗和归一化处理等缺点,因此我们可以对knn算法的实现方式进行优化,例如使用kd树等数据结构加速搜索过程,以减少计算量和存储空间(这点以后再说)。或者结合上其他的机器学习方法,如神经网络等,来提高knn算法的分类性能。