KNN(下):数据分析 | 数据挖掘 | 十大算法之一

news2025/1/19 14:22:29

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️
🐴作者:秋无之地

🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。

🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、留言💬、关注🤝,关注必回关

上一篇文章已经跟大家介绍过《KNN(上):数据分析 | 数据挖掘 | 十大算法之一》,相信大家对KNN(上)都有一个基本的认识。下面我讲一下,KNN(下):数据分析 | 数据挖掘 | 十大算法之一

KNN 实际上是计算待分类物体与其他物体之间的距离,然后通过统计最近的 K 个邻居的分类情况,来决定这个物体的分类情况。

一、如何在 sklearn 中使用 KNN

在 Python 的 sklearn 工具包中有 KNN 算法。KNN 既可以做分类器,也可以做回归。如果是做分类,你需要引用:

from sklearn.neighbors import KNeighborsClassifier

如果是做回归,你需要引用:

from sklearn.neighbors import KNeighborsRegressor

从名字上你也能看出来 Classifier 对应的是分类,Regressor 对应的是回归。一般来说如果一个算法有 Classifier 类,都能找到相应的 Regressor 类。比如在决策树分类中,你可以使用 DecisionTreeClassifier,也可以使用决策树来做回归 DecisionTreeRegressor。

好了,我们看下如何在 sklearn 中创建 KNN 分类器。

这里,我们使用构造函数 KNeighborsClassifier(n_neighbors=5, weights=‘uniform’, algorithm=‘auto’, leaf_size=30),这里有几个比较主要的参数,我分别来讲解下:

1.n_neighbors:即 KNN 中的 K 值,代表的是邻居的数量。K 值如果比较小,会造成过拟合。如果 K 值比较大,无法将未知物体分类出来。一般我们使用默认值 5。

2.weights:是用来确定邻居的权重,有三种方式:

  • weights=uniform,代表所有邻居的权重相同;
  • weights=distance,代表权重是距离的倒数,即与距离成反比;
  • 自定义函数,你可以自定义不同距离所对应的权重。大部分情况下不需要自己定义函数。

3.algorithm:用来规定计算邻居的方法,它有四种方式:

  • algorithm=auto,根据数据的情况自动选择适合的算法,默认情况选择 auto;
  • algorithm=kd_tree,也叫作 KD 树,是多维空间的数据结构,方便对关键数据进行检索,不过 KD 树适用于维度少的情况,一般维数不超过 20,如果维数大于 20 之后,效率反而会下降;
  • algorithm=ball_tree,也叫作球树,它和 KD 树一样都是多维空间的数据结果,不同于 KD 树,球树更适用于维度大的情况;
  • algorithm=brute,也叫作暴力搜索,它和 KD 树不同的地方是在于采用的是线性扫描,而不是通过构造树结构进行快速检索。当训练集大的时候,效率很低。

​4.leaf_size:代表构造 KD 树或球树时的叶子数,默认是 30,调整 leaf_size 会影响到树的构造和搜索速度。

创建完 KNN 分类器之后,我们就可以输入训练集对它进行训练,这里我们使用 fit() 函数,传入训练集中的样本特征矩阵和分类标识,会自动得到训练好的 KNN 分类器。然后可以使用 predict() 函数来对结果进行预测,这里传入测试集的特征矩阵,可以得到测试集的预测分类结果。

二、如何用 KNN 对手写数字进行识别分类

手写数字数据集是个非常有名的用于图像识别的数据集。数字识别的过程就是将这些图片与分类结果 0-9 一一对应起来。完整的手写数字数据集 MNIST 里面包括了 60000 个训练样本,以及 10000 个测试样本。如果你学习深度学习的话,MNIST 基本上是你接触的第一个数据集。

今天我们用 sklearn 自带的手写数字数据集做 KNN 分类,你可以把这个数据集理解成一个简版的 MNIST 数据集,它只包括了 1797 幅数字图像,每幅图像大小是 8*8 像素。

好了,我们先来规划下整个 KNN 分类的流程:

整个训练过程基本上都会包括三个阶段:

  1. 数据加载:我们可以直接从 sklearn 中加载自带的手写数字数据集;
  2. 准备阶段:在这个阶段中,我们需要对数据集有个初步的了解,比如样本的个数、图像长什么样、识别结果是怎样的。你可以通过可视化的方式来查看图像的呈现。通过数据规范化可以让数据都在同一个数量级的维度。另外,因为训练集是图像,每幅图像是个 8*8 的矩阵,我们不需要对它进行特征选择,将全部的图像数据作为特征值矩阵即可;
  3. 分类阶段:通过训练可以得到分类器,然后用测试集进行准确率的计算。

好了,按照上面的步骤,我们一起来实现下这个项目。

首先是加载数据和对数据的探索:

# 加载数据
digits = load_digits()
data = digits.data
# 数据探索
print(data.shape)
# 查看第一幅图像
print(digits.images[0])
# 第一幅图像代表的数字含义
print(digits.target[0])
# 将第一幅图像显示出来
plt.gray()
plt.imshow(digits.images[0])
plt.show()

运行结果:

(1797, 64)
[[ 0.  0.  5. 13.  9.  1.  0.  0.]
 [ 0.  0. 13. 15. 10. 15.  5.  0.]
 [ 0.  3. 15.  2.  0. 11.  8.  0.]
 [ 0.  4. 12.  0.  0.  8.  8.  0.]
 [ 0.  5.  8.  0.  0.  9.  8.  0.]
 [ 0.  4. 11.  0.  1. 12.  7.  0.]
 [ 0.  2. 14.  5. 10. 12.  0.  0.]
 [ 0.  0.  6. 13. 10.  0.  0.  0.]]
0

我们对原始数据集中的第一幅进行数据可视化,可以看到图像是个 8*8 的像素矩阵,上面这幅图像是一个“0”,从训练集的分类标注中我们也可以看到分类标注为“0”。

sklearn 自带的手写数字数据集一共包括了 1797 个样本,每幅图像都是 8*8 像素的矩阵。因为并没有专门的测试集,所以我们需要对数据集做划分,划分成训练集和测试集。因为 KNN 算法和距离定义相关,我们需要对数据进行规范化处理,采用 Z-Score 规范化,代码如下:

# 分割数据,将25%的数据作为测试集,其余作为训练集(你也可以指定其他比例的数据作为训练集)
train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size=0.25, random_state=33)
# 采用Z-Score规范化
ss = preprocessing.StandardScaler()
train_ss_x = ss.fit_transform(train_x)
test_ss_x = ss.transform(test_x)

然后我们构造一个 KNN 分类器 knn,把训练集的数据传入构造好的 knn,并通过测试集进行结果预测,与测试集的结果进行对比,得到 KNN 分类器准确率,代码如下:

# 创建KNN分类器
knn = KNeighborsClassifier() 
knn.fit(train_ss_x, train_y) 
predict_y = knn.predict(test_ss_x) 
print("KNN准确率: %.4lf" % accuracy_score(test_y, predict_y))

运行结果:

KNN准确率: 0.9756

好了,这样我们就构造好了一个 KNN 分类器。之前我们还讲过 SVM、朴素贝叶斯和决策树分类。我们用手写数字数据集一起来训练下这些分类器,然后对比下哪个分类器的效果更好。代码如下:

# 创建SVM分类器
svm = SVC()
svm.fit(train_ss_x, train_y)
predict_y=svm.predict(test_ss_x)
print('SVM准确率: %0.4lf' % accuracy_score(test_y, predict_y))
# 采用Min-Max规范化
mm = preprocessing.MinMaxScaler()
train_mm_x = mm.fit_transform(train_x)
test_mm_x = mm.transform(test_x)
# 创建Naive Bayes分类器
mnb = MultinomialNB()
mnb.fit(train_mm_x, train_y) 
predict_y = mnb.predict(test_mm_x) 
print("多项式朴素贝叶斯准确率: %.4lf" % accuracy_score(test_y, predict_y))
# 创建CART决策树分类器
dtc = DecisionTreeClassifier()
dtc.fit(train_mm_x, train_y) 
predict_y = dtc.predict(test_mm_x) 
print("CART决策树准确率: %.4lf" % accuracy_score(test_y, predict_y))

运行结果如下:

SVM准确率: 0.9867
多项式朴素贝叶斯准确率: 0.8844
CART决策树准确率: 0.8556

这里需要注意的是,我们在做多项式朴素贝叶斯分类的时候,传入的数据不能有负数。因为 Z-Score 会将数值规范化为一个标准的正态分布,即均值为 0,方差为 1,数值会包含负数。因此我们需要采用 Min-Max 规范化,将数据规范化到[0,1]范围内。​

​好了,我们整理下这 4 个分类器的结果。

你能看出来 KNN 的准确率还是不错的,和 SVM 不相上下。

你可以自己跑一遍整个代码,在运行前还需要 import 相关的工具包(下面的这些工具包你都会用到,所以都需要引用):

from sklearn.model_selection import train_test_split
from sklearn import preprocessing
from sklearn.metrics import accuracy_score
from sklearn.datasets import load_digits
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import SVC
from sklearn.naive_bayes import MultinomialNB
from sklearn.tree import DecisionTreeClassifier
import matplotlib.pyplot as plt

​代码中,我使用了 train_test_split 做数据集的拆分,使用 matplotlib.pyplot 工具包显示图像,使用 accuracy_score 进行分类器准确率的计算,使用 preprocessing 中的 StandardScaler 和 MinMaxScaler 做数据的规范化。

 三、总结

今天我带你一起做了手写数字分类识别的实战,分别用 KNN、SVM、朴素贝叶斯和决策树做分类器,并统计了四个分类器的准确率。在这个过程中你应该对数据探索、数据可视化、数据规范化、模型训练和结果评估的使用过程有了一定的体会。在数据量不大的情况下,使用 sklearn 还是方便的。

如果数据量很大,比如 MNIST 数据集中的 6 万个训练数据和 1 万个测试数据,那么采用深度学习 +GPU 运算的方式会更适合。因为深度学习的特点就是需要大量并行的重复计算,GPU 最擅长的就是做大量的并行计算。

版权声明

本文章版权归作者所有,未经作者允许禁止任何转载、采集,作者保留一切追究的权利。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1051837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

025 - STM32学习笔记 - 液晶屏控制(二) - 代码实现

025- STM32学习笔记 - 液晶屏控制(二) - 代码实现 好久没更新学习笔记了,最近工作上的事情太多了,趁着国庆中秋,多更新一点看看。 上节学习了关于LTDC与DMA2D以及显示屏的相关知识点,这节开始实操&#xf…

[谷粒商城笔记]08、环境-linux安装docker

1.查看是否已安装docker列表 yum list installed | grep docker 如果没有结果,则说明没有安装docker,我们就可以直接安装了。 2.安装docker: yum -y install docker 如果不是root账号,使用 sudo 以管理员身份运行 sudo yum -y install …

CentOS 7 安装 MySQL5.7

CentOS 7 安装 MySQL5.7 安装wget: yum -y install wget进入/usr/local/下: cd /usr/local/新建mysqlrpm文件夹: mkdir mysqlrpm进入mysqlrpm文件夹下: cd /usr/local/mysqlrpm/下载mysql包安装源: wget http://…

MySQL单表查询与多表查询

目录 一、单表查询 ​编辑 1、显示所有职工的基本信息。 ​编辑2、查询所有职工所属部门的部门号,不显示重复的部门号。 ​编辑3、求出所有职工的人数。 4、列出最高工和最低工资。 ​编辑5、列出职工的平均工资和总工资。 ​编辑6、创建一个只有职…

FreeRTOS两个死机原因(中断调用接口异常)【杂记】

1、中断回调函数中没有使用中断级API (xxFromISR) 函数 xSemaphoreGiveFromISR(uart_busy,&HighterTask);----正确 xSemaphoreGive(uart_busy);-----错误2、比configMAX_SYSCALL_INTERRUPT_PRIORITY优先级高的中断函数中使用了FreeRTOS的函数 3、临界代码保护后不可调用os…

安全基础 --- MySQL数据库的《锁》解析

MySQL的ACID (1)ACID是衡量事务的四个特性 原子性(Atomicity,或称不可分割性)一致性(Consistency)隔离性(Isolation)持久性(Durability) &…

(一)TinyWebServer的环境配置与运行

Linux下C轻量级Web服务器,项目来源于:TinyWebServer 配置环境(为下载代码,编译运行做准备) 1. 安装VMware VMware官网 选择产品,点击Workstation Pro 下载试用版(注:需要在官网注册…

Java自学(三)面向对象编程

目录 什么是面向对象 举例 this关键字和构造器 实体类 电影小案例 什么是面向对象 我们日常生活中谈到一个事物,总会描述它的性质与行为,这个事物也就是 ”对象”。比如一个学生对象,他的属性有姓名、学号、成绩......他的行为有上课、…

【C++】C++模板进阶 —— 非类型模板参数、模板的特化以及模板的分离编译

​ ​📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:C学习 🎯长路漫漫浩浩,万事皆有期待 上一篇博客:【C】C多…

史玉柱复出一年:巨人股权第三次被冻结,力推AI+游戏

大数据产业创新服务媒体 ——聚焦数据 改变商业 一则股权冻结信息,又一次将复出一年的史玉柱推上风口浪尖。 天眼查APP显示,巨人投资近日新增一则股权冻结信息,被执行人为史玉柱,冻结股权数额1.14亿元,冻结期限为三年…

Visual Studio 中将TAB设置为空格

将TAB设置为空格的原因很多,其中一点是为了统一不同编译器对TAB的解释,防止代码风格在不同编译器下不一致等。 在菜单中选择: 工具-->选项-->文本编辑器--->所有语言-->制表符 在窗口中选择,制表符大小和缩进大小都选为4&#xf…

【从入门到起飞】JavaSE—Stream流

🎊专栏【JavaSE】 🍔喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 🎆音乐分享【如愿】 🥰欢迎并且感谢大家指出我的问题 文章目录 🍔Stream流的作用🍔Stream流的使用步骤🎄获取Strea…

机器人过程自动化(RPA)入门 7. 处理用户事件和助手机器人

在UiPath中,有两种类型的Robot用于自动化任何流程。一个是后台机器人,它在后台工作。它独立工作,这意味着它不需要用户的输入或任何用户交互。另一个是前台机器人,也被称为助理机器人。 本章介绍前台机器人。在这里,我们将了解自动化过程中通过简单按键、单击鼠标等触发事…

代码随想录算法训练营第四十六天 | 动态规划 part 8 | 139.单词拆分、多重背包、背包问题总结

目录 139.单词拆分思路代码 多重背包背包问题总结 139.单词拆分 Leetcode 思路 dp[i] : 字符串长度为i的话,dp[i]为true,表示可以拆分为一个或多个在字典中出现的单词。如果确定dp[j] 是true,且 [j, i] 这个区间的子串出现在字典里&#xf…

仿真数据检查器如何比较数据

可以定制仿真数据检查器比较过程,以多种方式满足您的需求。在比较各运行时,仿真数据检查器会执行以下操作: 根据对齐设置,对齐基线运行和比较项运行中的信号对组。 仿真数据检查器不会比较无法对齐的信号。 根据指定的同步方法同…

Leetcode 剑指 Offer II 046. 二叉树的右视图

题目难度: 中等 原题链接 今天继续更新 Leetcode 的剑指 Offer(专项突击版)系列, 大家在公众号 算法精选 里回复 剑指offer2 就能看到该系列当前连载的所有文章了, 记得关注哦~ 题目描述 给定一个二叉树的 根节点 root,请找出该二叉树的 最底…

【中秋国庆不断更】OpenHarmony定义可动画属性:@AnimatableExtend装饰器

AnimatableExtend装饰器用于自定义可动画的属性方法,在这个属性方法中修改组件不可动画的属性。在动画执行过程时,通过逐帧回调函数修改不可动画属性值,让不可动画属性也能实现动画效果。 可动画属性:如果一个属性方法在animation…

批量剪辑视频软件,支持免费试用,合成视频,预览不限量不收费

几乎对于所有的短视频创作者来说,批量剪辑软件都是现在或者将来必备的办公软件。现如今市场上的批量剪辑软件也是层出不穷,质量也是良莠不齐。 今天给大家实实在在的推荐一款性价比非常高的批量剪辑软件——超级编导,适用于既想提升团队视频…

volatile关键字以及使用场景

在多线程环境下,如果编程不当,可能会出现程序运行结果混乱的问题。 出现这个原因主要是,JMM 中主内存和线程工作内存的数据不一致,以及多个线程执行时无序,共同导致的结果。 同时也提到引入synchronized同步锁&#x…

Android Studio插件版本与Gradle 版本对应关系

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。 专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。 目录 一、导读二、概览三、Gradle各版本对应关系3.1 Gradle 版…