knn算法python代码_Python—KNN分类算法(详解)
1. 概述
华冠丽服KNN 可以说是最简单的分类算法之⼀,同时,它也是最常⽤的分类算法之⼀。注意:KNN 算法是有监督学习中的分类算法,它看起来和另⼀个机器学习算法 K-means 有点像(K-means 是⽆监督学习算法),但却是有本质区别的。
2. 核⼼思想
KNN 的全称是 K Nearest Neighbors,意思是 K 个最近的邻居。从这个名字我们就能看出⼀些 KNN 算法的蛛丝马迹了。K 个最近邻居,毫⽆疑问,K 的取值肯定是⾄关重要的,那么最近的邻居⼜是怎么回事呢?其实,KNN 的原理就是当预测⼀个新的值 x 的时候,根据它距离最近的 K 个点是什么类别来判断 x 属于哪个类别。听起来有点绕,还是看看图吧。
花果茶图中绿⾊的点就是我们要预测的那个点,假设 K=3。那么 KNN 算法就会找到与它距离最近的三个点(这⾥⽤圆圈把它圈起来了),看看哪种类别多⼀些,⽐如这个例⼦中是蓝⾊三⾓形多⼀些,新来的绿⾊点就归类到蓝三⾓了。
但是,当 K=5 的时候,判定就变成不⼀样了。这次变成红圆多⼀些,所以新来的绿点被归类成红圆。从这个例⼦中,我们就能看得出K 的取值是很重要的。
明⽩了⼤概原理后,我们就来说⼀说细节的东西吧,主要有两个,K 值的选取和点距离的计算。
2.1 距离计算
要度量空间中点距离的话,有好⼏种度量⽅式,⽐如常见的曼哈顿距离计算、欧式距离计算等等。不过通常 KNN 算法中使⽤的是欧式距离。这⾥只是简单说⼀下,拿⼆维平⾯为例,⼆维空间两个点的欧式距离计算公式如下:
这个⾼中应该就有接触到的了,其实就是计算(x1,y1)和(x2,y2)的距离。拓展到多维空间,则公式变成这样:
这样我们就明⽩了如何计算距离。KNN 算法最简单粗暴的就是将预测点与所有点距离进⾏计算,然后保存并排序,选出前⾯ K 个值看看哪些类别⽐较多。但其实也可以通过⼀些数据结构来辅助,⽐如最⼤堆,这⾥就不多做介绍,有兴趣可以百度最⼤堆相关数据结构的知识。
2.2 K值选择
通过上⾯那张图我们知道 K 的取值⽐较重要,那么该如何确定 K 取多少值好呢?答案是通过交叉验证(将样本数据按照⼀定⽐例,拆分出训练⽤的数据和验证⽤的数据,⽐如6:4拆分出部分训练数据和验证数据),从选取⼀个较⼩的 K 值开始,不断增加 K 的值,然后计算验证集合的⽅差,最终找到⼀个⽐较合适的 K 值。
通过交叉验证计算⽅差后你⼤致会得到下⾯这样的图:
这个图其实很好理解,当你增⼤ K 的时候,⼀般错误率会先降低,因为有周围更多的样本可以借鉴了,分类效果会变好。但注意,和 K-means 不⼀样,当 K 值更⼤的时候,错误率会更⾼。这也很好理解,⽐如说你⼀共就35个样本,当你 K 增⼤到30的时候,KNN 基本上就没意义了。
所以选择 K 点的时候可以选择⼀个较⼤的临界 K 点,当它继续增⼤或减⼩的时候,错误率都会上升,⽐如图中的 K=10。
3. 算法实现
3.1 Sklearn KNN参数概述
要使⽤ Sklearn KNN 算法进⾏分类,我们需要先了解 Sklearn KNN 算法的⼀些基本参数:
def KNeighborsClassifier(n_neighbors = 5,
weights='uniform',
algorithm = '',
leaf_size = '30',
p = 2,
metric = 'minkowski',
metric_params = None,
n_jobs = None
)
其中:
n_neighbors:这个值就是指 KNN 中的 “K”了。前⾯说到过,通过调整 K 值,算法会有不同的效果。
weights(权重):最普遍的 KNN 算法⽆论距离如何,权重都⼀样,但有时候我们想搞点特殊化,⽐如距离更近的点让它更加重要。
这时候就需要 weight 这个参数了,这个参数有三个可选参数的值,决定了如何分配权重。参数选项如下:
* ‘uniform’:不管远近权重都⼀样,就是最普通的 KNN 算法的形式。
* ‘distance’:权重和距离成反⽐,距离预测⽬标越近具有越⾼的权重。
* ⾃定义函数:⾃定义⼀个函数,根据输⼊的坐标值返回对应的权重,达到⾃
定义权重的⽬的。
algorithm:在 Sklearn 中,要构建 KNN 模型有三种构建⽅式:
1. 暴⼒法,就是直接计算距离存储⽐较的那种⽅式。
2. 使⽤ Kd 树构建 KNN 模型。
3. 使⽤球树构建。
其中暴⼒法适合数据较⼩的⽅式,否则效率会⽐较低。如果数据量⽐较⼤⼀般会选择⽤ Kd 树构建 KNN 模型,⽽当 Kd 树也⽐较慢的时候,则可以试试球树来构建 KNN。参数选项如下:
* ‘brute’ :蛮⼒实现;
* ‘kd_tree’:KD 树实现 KNN;
* ‘ball_tree’:球树实现 KNN ;
* ‘auto’: 默认参数,⾃动选择合适的⽅法构建模型。
不过当数据较⼩或⽐较稀疏时,⽆论选择哪个最后都会使⽤ ‘brute’。
leaf_size:如果是选择蛮⼒实现,那么这个值是可以忽略的。当使⽤ Kd 树或球树,它就是停⽌建⼦树的叶⼦节点数量的阈值。默认30,但如果数据量增多这个参数需要增⼤,否则速度过慢不说,还容易过拟合。
p:和 metric 结合使⽤,当 metric 参数是 “minkowski” 的时候,p=1 为曼哈顿距离, p=2 为欧式距离。默认为p=2。
metric:指定距离度量⽅法,⼀般都是使⽤欧式距离。
定乎内外之分* ‘euclidean’ :欧式距离;
麻雀苏三省* ‘manhattan’:曼哈顿距离;
* ‘chebyshev’:切⽐雪夫距离;
* ‘minkowski’: 闵可夫斯基距离,默认参数。
n_jobs:指定多少个CPU进⾏运算,默认是-1,也就是全部都算。
蜂胶哪个牌子好
烤箱鸡米花3.2 KNN代码实例
KNN 算法算是机器学习⾥⾯最简单的算法之⼀了,我们来看 Sklearn 官⽅给出的例⼦是怎样使⽤KNN 的。
数据集使⽤的是著名的鸢尾花数据集,⽤ KNN 来对它做分类。我们先看看鸢尾花长的啥样:
上⾯这个就是鸢尾花了,这个鸢尾花数据集主要包含了鸢尾花的花萼长度、花萼宽度、花瓣长度、花瓣宽度4个属性(特征),以及鸢尾花卉属于『Setosa、Versicolour、Virginica』三个种类中的哪⼀类(这三种都长什么样我也不知道)。
在使⽤ KNN 算法之前,我们要先决定 K 的值是多少。要选出最优的 K 值,可以使⽤ Sklearn 中的交
叉验证⽅法,代码如下:脚踝疼
from sklearn.datats import load_iris对孩子的祝福语
del_lection import cross_val_score
import matplotlib.pyplot as plt
ighbors import KNeighborsClassifier
#读取鸢尾花数据集
iris = load_iris()
x = iris.data
y = iris.target
k_range = range(1, 31)
k_error = []
#循环,取k=1到k=31,查看误差效果
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
#cv参数决定数据集划分⽐例,这⾥是按照5:1划分训练集和测试集
scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy')
k_error.append(1 - an())
#画图,x轴为k值,y值为误差值
plt.plot(k_range, k_error)
plt.xlabel('Value of K for KNN')
plt.ylabel('Error')
plt.show()
运⾏后,我们可以得到下⾯这样的图:
有了这张图,我们就能明显看出 K 值取多少的时候误差最⼩,这⾥明显是 K=11 最好。当然在实际问
题中,如果数据集⽐较⼤,那为减少训练时间,K 的取值范围可以缩⼩。
有了 K 值我们就能运⾏ KNN 算法了,具体代码如下: