目录
现实问题:“物以类聚,人以群分”
一.KNN算法概述
二.KNN算法介绍
K近邻分类模型算法步骤
距离计算方式
KNN分类图
K值选择
三.KNN特点
KNN算法的优势和劣势
知识巩固
Python实战:KNN数据分类
拓展学习
现实问题:“物以类聚,人以群分”
同类的东西常聚在一起,志同道合的人相聚成群
一.KNN算法概述
KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一,注意KNN算法是有监督学习中的分类算法,它看起来和另一个机器学习算法Kmeans有点像(Kmeans是无监督学习算法),但却是有本质区别的。那么什么是KNN算法呢,接下来我们就来介绍介绍吧。
二.KNN算法介绍
KNN的全称是K Nearest Neighbors,意思是K个最近的邻居。通过计算新数据与训练数据之间的距离,然后选取K(K>=1)个距离最近的邻居进行分类判断(K个邻居), 这K个邻居的多数属于某个类,就把该新数据实例分类到这个类中。
举例:判断图中圆圈属于哪个类别
- K=3,绿色圆点(50,50)的最近的3个邻居是2个红色小三角形(60,50)、(50,60)和1个蓝色小正方形(40,40),判定其属于红色的三角形一类。
- K=5,绿色圆点的最近的5个邻居是2个红色三角形(60,50)、(50,60)和3个蓝色的正方形(40,40)、(40,80)、(30,60),判定其属于蓝色的正方形一类。
K近邻分类模型算法步骤
(1)计算训练数据集每个样本x_i与新的样本数据x_test的距离d_(i-test) ;
(2)将计算出的距离按照升序排列,并取出前K个距离最小的样本;
(3)统计这K个样本的标签值𝑦y ,并找出出现频率最高的标签;
(4)新的样本数据x_test的标签值y_test即为该频率最高的标签值。
距离计算方式
欧氏距离:两点之间的直线距离,KNN计算中应用最多的距离。
曼哈顿距离:两个点在标准坐标系上的绝对轴距总和
KNN分类图
K值选择
通过上面那张图我们知道K的取值比较重要,那么该如何确定K取多少值好呢?答案是通过交叉验证(将样本数据按照一定比例,拆分出训练用的数据和验证用的数据,比如6:4拆分出部分训练数据和验证数据),从选取一个较小的K值开始,不断增加K的值,然后计算验证集合的方差,最终找到一个比较合适的K值。
通过交叉验证计算方差后你大致会得到下面这样的图:
这个图其实很好理解,当你增大k的时候,一般错误率会先降低,因为有周围更多的样本可以借鉴了,分类效果会变好。但注意,和K-means不一样,当K值更大的时候,错误率会更高。这也很好理解,比如说你一共就35个样本,当你K增大到30的时候,KNN基本上就没意义了。
所以选择K点的时候可以选择一个较大的临界K点,当它继续增大或减小的时候,错误率都会上升,比如图中的K=10。
三.KNN特点
KNN是一种非参的,惰性的算法模型。什么是非参,什么是惰性呢?
非参的意思并不是说这个算法不需要参数,而是意味着这个模型不会对数据做出任何的假设,与之相对的是线性回归(我们总会假设线性回归是一条直线)。也就是说KNN建立的模型结构是根据数据来决定的,这也比较符合现实的情况,毕竟在现实中的情况往往与理论上的假设是不相符的。
惰性又是什么意思呢?想想看,同样是分类算法,逻辑回归需要先对数据进行大量训练(tranning),最后才会得到一个算法模型。而KNN算法却不需要,它没有明确的训练数据的过程,或者说这个过程很快。
KNN算法的优势和劣势
了解KNN算法的优势和劣势,可以帮助我们在选择学习算法的时候做出更加明智的决定。那我们就来看看KNN算法都有哪些优势以及其缺陷所在!
KNN算法优点
- 简单易用,相比其他算法,KNN算是比较简洁明了的算法。即使没有很高的数学基础也能搞清楚它的原理。
- 模型训练时间快,上面说到KNN算法是惰性的,这里也就不再过多讲述。
- 预测效果好。
- 对异常值不敏感
KNN算法缺点
- 对内存要求较高,因为该算法存储了所有训练数据
- 预测阶段可能很慢
- 对不相关的功能和数据规模敏感
当需要使用分类算法,且数据比较大的时候就可以尝试使用KNN算法进行分类了。
知识巩固
问题:训练数据集如下表所示
新数据(3,2,7,-1),计算其与训练数据各点的欧氏距离、曼哈顿距离,并基于KNN算法原理判断其类别(K=2)
Python实战:KNN数据分类
基础环境: Python语言;安装核心工具包numpy、pandas、sklearn、matplotlib;环境管理软件Anaconda;Jupyter notebook
环境配置参考:机器学习入门与Python实战核心工具篇:pip源、python、anaconda、工具包(完整版)
任务:基于2D_data数据,建立KNN模型,实现数据分类。
#数据加载
import pandas as pd
import numpy as np
#data = pd.read_csv('task1_data1.csv')
data_result = pd.read_csv('task1_data2.csv')
#data.head()
data_result.head()
#X 赋值
X = data_result.drop(['y'],axis=1)
X.head()
#正确结果的赋值
y = data_result.loc[:,'y']
y.head()
fig2 = plt.figure()
plt.scatter(X.loc[:,'x1'][y==0],X.loc[:,'x2'][y==0],label='label0')
plt.scatter(X.loc[:,'x1'][y==1],X.loc[:,'x2'][y==1],label='label1')
#plt.scatter(X_labeled['x1'],X_labeled['x2'],label='labeled')
plt.title('labeled data')
plt.xlabel('x1')
plt.ylabel('x2')
plt.legend(loc='upper left')
plt.show()
#knn建模部分 knn建模与训练
# print(X)
# print(y)
from sklearn.neighbors import KNeighborsClassifier
KNN = KNeighborsClassifier(n_neighbors=3)
KNN.fit(X,y)
#knn预测
y_predict_knn = KNN.predict(X)
accuracy_knn = accuracy_score(y,y_predict_knn)
print(accuracy_knn)
#统计类别分布
print(pd.value_counts(y_predict_knn))
print(pd.value_counts(y))