原理
存在一个样本数据集合,也称作为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。输入没有标签的新数据后,将新的数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本最相似数据(最近邻)的分类标签。
-
那么如何进行比较呢?
KNN算法采用距离度量的方法
将未知类别的新数据与训练样本之间计算距离,认为和距离近的数据的类别相同
距离公式
代码实现及解析
首先进行数据预处理(此处选择较为简单的数据,进行简单的预处理,方便理解)
import numpy as np#后续还有需要import的函数在后面说明
import matplotlib.pyplot as plt
raw_data_x=[[3.39,2.33],
[3.22,1.78],
[1.34,3.36],
[3.58,4.67],
[2.28,2.86],
[7.42,4.69],
[5.74,3.53],
[9.17,2.52],
[7.79,3.42],
[7.94,0.79]
]#原始数据,用作训练集
raw_data_y=[0,0,0,0,0,1,1,1,1,1]#原始标签
X_train=np.array(raw_data_x)
Y_train=np.array(raw_data_y)#进行数据的预处理,变成矩阵和向量
为了便于观察,我们先做出训练集的散点图(对数据可视化若有疑惑可查阅我的上篇博文)
plt.scatter(X_train[Y_train==0,0],X_train[Y_train==0,1],color='g')
plt.scatter(X_train[Y_train==1,0],X_train[Y_train==1,1],color='r')
plt.show#将训练数据绘制散点图
![](https://img.haomeiwen.com/i19479038/e862a8c35eeb68e3.png)
这里将不同类别的元素颜色取了不同方便观察
接下来是计算距离的过程,也是knn算法的核心
x=np.array([8.09,3.36])#现来预测一个新x值该如何分类
#KNN过程
from math import sqrt
distance=[]#新建一个空的距离列表,用于存放距离数据
for x_train in X_train:
d=sqrt(np.sum((x_train - x)**2))#计算出距离,需要用到sqrt函数
distance.append(d)
#使用列表推导式可以简化
#distance=[sqrt(np.sum((x_train - x)**2)) for x_train in X_train]
#接下来要进行排序,来了解究竟是哪些点离他最近
![](https://img.haomeiwen.com/i19479038/0de69a5e43e2130b.png)
既然我们已经完成了计算过程,我们接下来需要分析最近邻里面类别最多的是哪一类,来作为最后的分类结果
nearest=np.argsort(distance)#将索引列表存起来
k=6#后面会知道,这里是选取前k个最近的,然后进行统计,看看前k个最近里所属类别最多的是谁
topk_y=[Y_train[i] for i in nearest[:k]]#最近k个点相应的y值即标签值,i是nearst数组中的前k个元素
#比如说第一个元素是8,则i赋8,找到y_train中第8个元素即标签
#接下来要对返回的标签值列表进行统计,返回最多的那个类
from collections import Counter
votes=Counter(topk_y)#返回一个字典
votes.most_common(1)#找出票数最多的1个元素,返回一个数组[(1,5)]
predict_y=votes.most_common(1)[0][0]#取出类别
predict_y
这样,我们就成功预测出了x的类别为1
![](https://img.haomeiwen.com/i19479038/8c0a74daa74a14e3.png)
使用scikit-learn中的knn
使用scikit-learn模块时必须按照模块规定的流程化进行,实际上这个流程也是机器学习的大多数流程
![](https://img.haomeiwen.com/i19479038/768afd6c379d9bfc.png)
似乎KNN算法并不需要拟合模型这一个过程,直接输入未知量便可以得到输出结果,但是在使用这一类机器学习模块时,我们还是得按照这个流程进行
from sklearn.neighbors import KNeighborsClassifier
kNN_classifier = KNeighborsClassifier(n_neighbors=6)
#由于机器学习模块是以面向对象的形式封装的,所以我们需要先创建一个实例
#这里的n_neighbors为我们之前遇到的k值
kNN_classifier.fit(X_train,Y_train)#训练以建立模型
X=x.reshape(1,-1)#将需要预测的值转为矩阵形式,以满足这个模块的要求
y_predict=kNN_classifier.predict(X)#返回预测值数组
y_predict[0]
![](https://img.haomeiwen.com/i19479038/3889eb9e97c137d6.png)
总结
KNN是一种不需要训练过程的算法,或者可以认为是没有模型的算法,实际上这里只讨论了很简单的距离度量方法,还有切比雪夫距离、马氏距离、巴氏距离等,至于k近邻算法的优缺点,这里引用Jack-Cui博客里面的总结
![](https://img.haomeiwen.com/i19479038/c5a3ba7a3eaa657f.png)
![](https://img.haomeiwen.com/i19479038/5ac470366750cb8b.png)
- knn算法是一种简单易用适合入门学习的算法,其用途也比较多,但是仅仅是这些疏浅的知识显然不足以面对实际情况中可能出现的问题,下篇博文会补充knn中需要注意的一些问题,同时也是整个机器学习中的一些比较普遍的现象。
网友评论