python实现KNN分类(自动选取K值)

您所在的位置:网站首页 模型k值 python实现KNN分类(自动选取K值)

python实现KNN分类(自动选取K值)

2024-07-15 15:46:40| 来源: 网络整理| 查看: 265

上文我们介绍了KNN的原理及实现过程,现在我们通过python实现它。

一、可视化实现KNN

首先,我们先手动选取多个k值进行可视化比较。

可视化结果:对已知的数据点与对应的标签,测试在不同k值的情况下,包括所有已知点的矩形区域的分类标签,先放上结果:

选用数据集:鸢尾花数据集,数据特征取前两个特征(方便可视化)

数据集简介:

如图(太长截取一部分),数据集共有150行,有三个标签0,1,2 (实际为'setosa', 'versicolor', 'virginica'三种鸢尾花花型,导入数据后程序会自动转为数字标签方便处理,可以通过data.target_names查看标签实际名字),有四个数据特征('sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'),前0~49个数据是对应标签0的数据,50~99是对应标签1的数据,100~149是对应标签2的数据。为方便可视化,数据特征先只取前两个特征。

导入库文件与数据集:

import numpy as np import matplotlib.pyplot as plt from matplotlib.colors import ListedColormap from sklearn.neighbors import KNeighborsClassifier from sklearn import datasets # 使用莺尾花数据集的前两维数据,便于数据可视化 iris = datasets.load_iris() X = iris.data[:, :2] y = iris.target

建立k值的列表,方便之后程序分别计算比较:

k_list = [1, 3, 5, 8, 10, 15]

创建画布颜色与图形:

# 创建不同颜色的画布 cmap_light = ListedColormap(['orange', 'cyan', 'red']) plt.figure(figsize=(15,14))

对不同的k进行循环遍历,计算由数据特征点最小值与最大值围成的矩形网格点所属的类别(程序中的矩形大1是为了图形更加清楚):

for ind,k in enumerate(k_list): clf = KNeighborsClassifier(k) clf.fit(X, y) # 画出决策边界 x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1 y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # 根据边界填充颜色 Z = Z.reshape(xx.shape) plt.subplot(321+ind) plt.pcolormesh(xx, yy, Z, cmap=cmap_light, shading='auto') # 数据点可视化到画布 plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_light, edgecolor='k', s=20) plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) plt.title("3-Class classification (k = %i)"% k) plt.show()

其中的一些函数的解释:

enumerate函数:将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中,举例说明:

图源:https://www.runoob.com/python/python-func-enumerate.html

python中KNN分类器:KNeighborsClassifier(k),参数k为knn算法中的k值

subplot函数:使一个figure对象可以包含多个子图,形式为:

subplot(numRows, numCols, plotNum)

图表的整个绘图区域被分成 numRows行和 numCols列,plotNum表示目前正在绘制第plotNum个子图,如果 numRows, numCols和 plotNum这三个数都小于 10 的话, 可以把它们缩写为一个整数, 例如 subplot(323) 和 subplot(3,2,3) 是相同的,表示子图排列成3行2列,正在绘制第3个子图。

结果:

可以看出:如果选择较小的K值,就相当于用较小的领域中的训练实例进行预测,例如当k=1的时候,在分界点位置的数据很容易受到局部的影响,图中蓝色的部分中还有部分绿色块,主要是数据太局部敏感。当k=15的时候,不同的数据基本根据颜色分开,当时进行预测的时候,会直接落到对应的区域,模型相对更加鲁棒。

二、鸢尾花数据集knn分类

现在我们再把所有的特征数据考虑进去,先选取k值为5,代码如下:

# 加载莺尾花数据集 from sklearn import datasets # 导入KNN分类器 from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split # 导入莺尾花数据集 iris = datasets.load_iris() X = iris.data y = iris.target # 得到训练集合和验证集合, 8: 2 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state= 2020) # 训练模型 clf = KNeighborsClassifier(5) clf.fit(X_train, y_train) # 预测 y_pred = clf.predict(X_test) print("预估值:\n",y_pred) acc = sum(y_pred == y_test) / y_pred.shape[0] print("预测的准确率ACC: %.2f%%" % (acc*100))

结果为:

预估值: [2 0 1 1 1 1 2 1 0 0 2 1 0 2 2 0 1 1 2 0 0 2 2 0 2 1 1 1 0 0] 真实值: [2 0 1 1 1 2 2 1 0 0 2 2 0 2 2 0 1 1 2 0 0 2 1 0 2 1 1 1 0 0] 预测的准确率ACC: 90.00%三、网格搜索自动选取k值

之前我们说过k值的选取非常重要,可通过交叉验证集来求取最优的k值。所以,我们现在通过网格搜索算法求取最优值,网格搜索算法是啥?实际就是选取参数范围后遍历所以参数,取最优的那一个,和我们在(一)中遍历类似。(当然优化算法不只网格搜索,这里的数据不多且计算较简单,所以我们采用网格搜索来调参)

求最优的算法选好了,验证集怎么选?目前选取验证集有多种方法:Holdout Method(保留)、K-fold Cross Validation(k折叠)、Leave-One-Out Cross Validation(留一)

Holdout Method(保留)方法:将原始数据随机分为两组,一组做为训练集,一组做为验证集,利用训练集训练分类器,然后利用验证集验证模型,记录最后的分类准确率为此Hold-OutMethod下分类器的性能指标.。Holdout Method相对于K-fold Cross Validation 又称Double cross-validation ,或相对K-CV称 2-fold cross-validation(2-CV)优点:好处的处理简单,只需随机把原始数据分为两组即可缺点:严格意义来说Holdout Method并不能算是CV,因为这种方法没有达到交叉的思想,由于是随机的将原始数据分组,所以最后验证集分类准确率的高低与原始数据的分组有很大的关系,所以这种方法得到的结果其实并不具有说服性.(主要原因是 训练集样本数太少,通常不足以代表母体样本的分布,导致 test 阶段辨识率容易出现明显落差。此外,2-CV 中一分为二的分子集方法的变异度大,往往无法达到「实验过程必须可以被复制」的要求。)K-fold Cross Validation(k折叠)方法:作为Holdout Methon的演进,将原始数据分成K组(一般是均分),将每个子集数据分别做一次验证集,其余的K-1组子集数据作为训练集,这样会得到K个模型,用这K个模型最终的验证集的分类准确率的平均数作为此K-CV下分类器的性能指标.K一般大于等于2,实际操作时一般从3开始取,只有在原始数据集合数据量小的时候才会尝试取2. 而K-CV 的实验共需要建立 k 个models,并计算 k 次 test sets 的平均辨识率。在实作上,k 要够大才能使各回合中的 训练样本数够多,一般而言 k=10 (作为一个经验参数)算是相当足够了。优点:K-CV可以有效的避免过学习以及欠学习状态的发生,最后得到的结果也比较具有说服性.缺点:K值选取上Leave-One-Out Cross Validation(留一)方法:如果设原始数据有N个样本,那么留一就是N-CV,即每个样本单独作为验证集,其余的N-1个样本作为训练集,所以留一会得到N个模型,用这N个模型最终的验证集的分类准确率的平均数作为此下LOO-CV分类器的性能指标.优点:相比于前面的K-CV,留一有两个明显的优点: a.每一回合中几乎所有的样本皆用于训练模型,因此最接近原始样本的分布,这样评估所得的结果比较可靠。b. 实验过程中没有随机因素会影响实验数据,确保实验过程是可以被复制的.缺点:计算成本高,因为需要建立的模型数量与原始数据样本数量相同,当原始数据样本数量相当多时,LOO-CV在实作上便有困难几乎就是不显示,除非每次训练分类器得到模型的速度很快,或是可以用并行化计算减少计算所需的时间。引用源:https://blog.csdn.net/u010967162/article/details/52269077

sklearn库中网格搜索采用k折叠交叉验证进行。

明确了方法与验证集,我们开始实验,选择k值的范围为1~50,选择10折交叉验证,只需在原先代码中加入:

clf = KNeighborsClassifier() para = range(1,50) param_dict = {"n_neighbors": para} # 预测K值 clf = GridSearchCV(clf, param_grid=param_dict, cv=10) clf.fit(X_train, y_train)

完整代码如下:

# 加载莺尾花数据集 from sklearn import datasets # 导入KNN分类器 from sklearn.neighbors import KNeighborsClassifier from sklearn.model_selection import train_test_split from sklearn.model_selection import GridSearchCV # 导入莺尾花数据集 iris = datasets.load_iris() X = iris.data y = iris.target # 得到训练集合和验证集合, 8: 2 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state= 2020) clf = KNeighborsClassifier() para = range(1,50) param_dict = {"n_neighbors": para} # 预测K值 clf = GridSearchCV(clf, param_grid=param_dict, cv=10) clf.fit(X_train, y_train) #最佳参数 print("最佳参数:\n",clf.best_params_) # 最佳结果 print("验证集中的最佳结果:\n", clf.best_score_) # 预测 y_pred = clf.predict(X_test) print("预估值:\n",y_pred) print("真实值:\n",y_test) acc = sum(y_pred == y_test) / y_pred.shape[0] print("预测的准确率ACC: %.2f%%" % (acc*100))

结果如下:

最佳参数: {'n_neighbors': 7} 验证集中的最佳结果: 0.9916666666666666 预估值: [2 0 1 1 1 2 2 1 0 0 2 1 0 2 2 0 1 1 2 0 0 2 2 0 2 1 1 1 0 0] 真实值: [2 0 1 1 1 2 2 1 0 0 2 2 0 2 2 0 1 1 2 0 0 2 1 0 2 1 1 1 0 0] 预测的准确率ACC: 93.33%

所以,通过网格搜索,自动计算出的k值为7,准确率要好于(二)中的90%

但是需要注意的是:

有时利用网格搜索交叉验证集的算法对测试集的计算结果并不一定好于自己凭借经验选的参数值!

因为算法优化参数是通过验证集的误差或损失值进行优化的,所以,保证训练集、验证集、测试集的广泛性很重要

同时验证集的选取方法不同,计算的结果准确度也可能不同

但当你不知道如何选取参数时,建议采用优化算法自动选取参数

四、参考

阿里云-天池龙珠计划



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭