利用knn算法实现手写数字分类

news2025/3/22 8:43:31

利用knn算法实现手写数字分类

  • 1.作者介绍
  • 2.KNN算法
    • 2.1KNN(K-Nearest Neighbors)算法核心思想
    • 2.2KNN算法的工作流程
    • 2.3优缺点
    • 2.4 KNN算法图示介绍
  • 3.实验过程
    • 3.1安装所需库
    • 3.2 MNIST数据集
    • 3.3 导入手写数字图像进行分类
    • 3.4 完整代码
    • 3.5 实验结果

1.作者介绍

王鹏飞,男,西安工程大学电子信息学院,2024级研究生
研究方向:机器视觉与人工智能
电子邮件:2018659934@QQ.com

王海博, 男 , 西安工程大学电子信息学院, 2024级研究生, 张宏伟人工智能课题组
研究方向:模式识别与人工智能
电子邮件:1137460680@qq.com

2.KNN算法

2.1KNN(K-Nearest Neighbors)算法核心思想

将训练数据保存下来,对于一个新的数据点,通过查看其在特征空间中最近的K个邻居来预测其类别或值。针对分类任务:如果K个邻居中多数属于某个类别,那么新数据点也被归为该类别。

2.2KNN算法的工作流程

(1) 数据准备
特征提取:将数据集中的每个样本表示为特征向量。
数据标准化:由于KNN依赖距离计算,因此需要对特征进行标准化(如归一化或Z分数标准化),以消除不同特征量纲的影响。

(2) 距离计算
对于一个新的数据点,计算它与数据集中每个点之间的距离。常用的距离度量方式包括:欧氏距离、曼哈顿距离和明可夫斯基距离。

(3) 确定最近邻
根据计算出的距离,找出与新数据点距离最近的K个点,这K个点称为“最近邻”。
K是一个超参数,需要根据具体问题选择合适的值。K值过小可能导致过拟合,K值过大可能导致模型过于平滑。

(4) 进行预测
分类任务:统计K个最近邻中每个类别的出现频率,选择出现次数最多的类别作为新数据点的预测类别。

2.3优缺点

(1) 优点
简单易实现:原理直观,实现代码简单。
无需训练:KNN不需要像其他算法那样进行复杂的训练过程,只需在预测时计算距离。
对复杂数据集表现良好:可以很好地处理多类别问题和非线性数据。
(2) 缺点
计算效率低:每次预测都需要计算新数据点与所有训练数据点之间的距离,计算量大。
存储需求高:需要存储整个训练数据集。
对K值和距离度量敏感:K值的选择和距离度量方式对模型性能影响较大。

2.4 KNN算法图示介绍

在这里插入图片描述
见上图所示,五角星为新输入的数据,原训练数据有Class A和Class B两类,对于新输入的数据,根据特征向量计算新输入数据点与训练集数据点之间的距离,根据所选K值确定出,新数据最邻近K个点,图示第一次k值选取为3时,其中Class B类占2/3,所以新数据将被分类为Class B类。
当k值选取为6时,见上图所示,Class A类占4/6,所以此时对于新数据点将被归为Class A类。由此可见K值的选择对于分类的结果存在一定的影响,因此k值的选择对于结果有重要的作用。

3.实验过程

3.1安装所需库

import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, classification_report
import cv2
from PIL import Image
import matplotlib.pyplot as plt

在编写代码前需要安装上述的库和所需的函数。

3.2 MNIST数据集

MNIST数据集来自美国国家标准与技术研究所。训练集由来自250个不同人手写的数字构成,测试集也是同样的手写数字数据,保证了测试集和训练集的作者集不相交。MNIST数据集一共有7万张图片,其中6万张是训练集,1万张是测试集。每张图片是28 × 28像素 的0 − 9的手写数字图片组成。每个图片是黑底白字的灰度图像。MNIST数据集可以导入fetch_openml函数从OpenML平台加载数据集。

3.3 导入手写数字图像进行分类

# 导入自定义图像并进行预测
def preprocess_image(image_path):
   
    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    image = cv2.resize(image, (28, 28))
    image = cv2.bitwise_not(image)
    image = image.reshape(1, -1)
    image = scaler.transform(image)
    return image
def predict_image(image_path):
    image = preprocess_image(image_path)
    prediction = knn.predict(image)
    return prediction[0]
print("Testing custom image...")
image_path = "d:/wenjian/1.jpg"  #更改为自己的路径
prediction = predict_image(image_path)
print(f"Predicted digit: {prediction}")
# 显示图像
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image, (28, 28))
image = cv2.bitwise_not(image)
plt.imshow(image, cmap="gray")
plt.title(f"Predicted Digit: {prediction}")
plt.show()

导入一张白底黑字的手写数字图像,并对图像进行预处理使得格式和灰度值与其训练集相同,本次实验导入的是白底黑字的手写数字图像,因为距离计算是依据灰度图像的灰度值进行计算,训练集的图像是黑底白字的灰度图像,因此需要对灰度值进行反转,否则会造成预测误差较大。导入图像路径需更改为自己图像路径。

3.4 完整代码

import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, classification_report
import cv2
from PIL import Image
import matplotlib.pyplot as plt

# 加载MNIST数据集
print("Loading MNIST dataset...")
mnist = fetch_openml('mnist_784', version=1)
X, y = mnist["data"], mnist["target"]
y = y.astype(np.uint8)
# 数据预处理
print("Preprocessing data...")
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)
# 训练KNN模型
print("Training KNN model...")
knn = KNeighborsClassifier(n_neighbors=5)
knn.fit(X_train, y_train)
# 评估模型
print("Evaluating model...")
y_pred = knn.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.4f}")
print(classification_report(y_test, y_pred))
# 导入自定义图像并进行预测
def preprocess_image(image_path):
   
    image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    image = cv2.resize(image, (28, 28))
    image = cv2.bitwise_not(image)
    image = image.reshape(1, -1)
    image = scaler.transform(image)
    return image
def predict_image(image_path):
    image = preprocess_image(image_path)
    prediction = knn.predict(image)
    return prediction[0]
print("Testing custom image...")
image_path = "d:/wenjian/1.jpg"  #更改为自己的路径
prediction = predict_image(image_path)
print(f"Predicted digit: {prediction}")
# 显示图像
image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
image = cv2.resize(image, (28, 28))
image = cv2.bitwise_not(image)
plt.imshow(image, cmap="gray")
plt.title(f"Predicted Digit: {prediction}")
plt.show()

3.5 实验结果

在这里插入图片描述

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

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

相关文章

基于springboot+vue的调查问卷平台

一、系统架构 前端:vue | element-ui | echarts 后端:springboot | mybatis-plus 环境:jdk1.8 | mysql | maven 二、代码及数据 三、功能介绍 01. 注册 02. 登录 03. web端-问卷中心 04. web端-文章中心 05. 管理端-…

美摄接入DeepSeek等大模型,用多模态融合重构视频创作新边界!

今年以来,DeepSeek凭借其强大的深度推理分析能力,在AI领域掀起新的热潮。美摄科技快速响应市场需求,迅速接入以DeepSeek、通义千问、商汤、文心一言为代表的大模型,为企业视频创作生产带来全新体验。 传统视频创作面临着同质化、…

网络编程之客户端聊天(服务器加客户端共三种方式)

最终效果&#xff1a; serve.c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include <sys/select.h>#define MAX_CLIENTS 2 // 只允许两个客户端 #define BUF_SIZE 1024i…

图莫斯TOOMOSS上位机TCANLINPro使用CAN UDS功能时 编写、加载27服务dll解锁算法文件

【本文发布于https://blog.csdn.net/Stack_/article/details/146303690&#xff0c;未经许可不得转载&#xff0c;转载须注明出处】 软件安装目录下找到如下压缩包&#xff0c;此为dll文件示例工程 使用VisualStudio打开工程GenerateKeyExImpl.vcxproj&#xff0c;可能会提示版…

vue+echarts实现饼图组件(实现左右联动并且数据量大时可滚动)

pieChart.vue(直接cv即可) <template><div class"rBox1"><div id"rBox1"></div></div> </template><script> export default {name: "pieChart",dicts: [],props: {subtext: {type: String,default…

Linux vim mode | raw / cooked

注&#xff1a;机翻&#xff0c;未校。 vim terminal “raw” mode Vim 终端 “raw” 模式 1. 原始模式与已处理模式的区别 We know vim puts the terminal in “raw” mode where it receives keystrokes as they are typed, opposed to “cooked” mode where the command…

IMX8MP Android 10系统编译SDK

概述&#xff1a; 本文描述了在Ubuntu 20.04操作系统上搭建IMX8MP Android10系统编译环境。 ubuntu主机端设置 1. ubuntu 20.04 1. 450G Free Disk space 2. 16GB RAM以上 3. 安装 sudo apt-get install uuid uuid-dev zlib1g-dev liblz-dev liblzo2-2 liblzo2-dev lzop …

ICLR 2025 机器人智能灵巧操作更进一步DexTrack

现实世界的机器人距离科幻小说里的机器人世界还有多远&#xff1f;通用灵巧操控何时才能实现&#xff1f;朝着这一伟大的目标&#xff0c;研究通用灵巧操控轨迹跟踪的 DexTrack 便应运而生。 论文地址&#xff1a;https://arxiv.org/abs/2502.09614代码地址&#xff1a;https:/…

Golang开发

Golang 文章目录 Golang预备技术一、算法与数据结构第1章&#xff1a;基础算法第2章&#xff1a;数据结构第3章&#xff1a;搜索与图论第4章&#xff1a;数论第5章&#xff1a;动态规划第6章&#xff1a;贪心第7章&#xff1a;算法竞赛入门 二、Linux操作系统与Shell编程三、计…

AI入门7:python三种API方式调用本地Ollama+DeepSeek

回顾 书接上篇&#xff1a;各种方式搭建了本地知识库&#xff1a; AI入门&#xff1a;AI模型管家婆ollama的安装和使用-CSDN博客 AI入门2&#xff1a;本地AI部署&#xff0c;用ollama部署deepseek&#xff08;私有化部署&#xff09;-CSDN博客 AI入门3&#xff1a;给本地d…

《线程池:Linux平台编译线程池动态库发生的死锁问题》

关于如何编译动态库可以移步《Linux&#xff1a;动态库动态链接与静态库静态链接》-CSDN博客 我们写的线程池代码是闭源的&#xff0c;未来想提供给别人使用&#xff0c;只需要提供so库和头文件即可。 系统默认库文件路径为&#xff1a; usr/lib usr/loacl/lib 系统默认头文件…

Python Bug修复案例分析:Python 中常见的 IndentationError 错误 bug 的修复

在 Python 编程的世界里&#xff0c;代码的可读性和规范性至关重要。Python 通过强制使用缩进来表示代码块的层次结构&#xff0c;这一独特的设计理念使得代码更加清晰易读。然而&#xff0c;正是这种对缩进的严格要求&#xff0c;导致开发者在编写代码时&#xff0c;稍有不慎就…

OpenCV旋转估计(1)用于估计图像间仿射变换关系的类cv::detail::AffineBasedEstimator

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 基于仿射变换的估计器。 这种估计器使用匹配器估算的成对变换来为每个相机估算最终的变换。 cv::detail::AffineBasedEstimator 是 OpenCV 库中…

c++类和对象(下篇)下

下面就来补充一下c雷和对象最后一点内容. 首先先补充一下上一篇博客上c类和对象(下篇)上-CSDN博客最后学习的静态成员变量的小练习求123...n_牛客题霸_牛客网 (nowcoder.com)下面就是题解.灵活的运用了静态成员变量不销毁的特点,建立数组利用构造函数来完成n次相加. class A{ …

使用WebDAV将文件传输到实时(RT)目标 转发

如何配置Web分布式创作和版本控制&#xff08;WebDAV&#xff09;服务器并使用它来与我的实时(RT)目标之间传输文件&#xff1f; 在目标上安装 WebDAV 和 SSL 支持 NI Linux Real-Time 您无需完成任何安装 WebDAV 和 SSL 支持的步骤。默认情况下&#xff0c;这些组件在NI Linu…

Web爬虫利器FireCrawl:全方位助力AI训练与高效数据抓取

Web爬虫利器FireCrawl&#xff1a;全方位助力AI训练与高效数据抓取 一、FireCrawl 项目简介二、主要功能三、FireCrawl应用场景1. 大语言模型训练2. 检索增强生成&#xff08;RAG&#xff09;&#xff1a;3. 数据驱动的开发项目4. SEO 与内容优化5. 在线服务与工具集成 四、安装…

如何避免PRD(需求文档)成为“沟通黑洞”

在撰写PRD&#xff08;需求文档&#xff09;时&#xff0c;要避免成为“沟通黑洞”&#xff0c;必须聚焦目标清晰、需求拆解、协同评审、持续迭代等关键点。其中&#xff0c;协同评审尤其重要——通过在文档完成初期就邀请相关部门共同审阅讨论&#xff0c;可以及早发现需求逻辑…

巧用符号链接搬移C盘中的软件数据目录到其他盘

#工作记录 我们知道&#xff0c;在Windows11系统&#xff0c;有些软件是不能指定安装目录的&#xff0c;有些软件即使指定了安装目录可是在更新版本之后还是会安装到默认的C盘目录中&#xff08;比如剪映&#xff09;&#xff0c;而且每次安装某些软件之后&#xff0c;这些软件…

使用 PIC 微控制器和 Adafruit IO 的基于 IoT 的 Web 控制家庭自动化

使用 PIC 微控制器和 Adafruit IO 的基于 IoT 的 Web 控制家庭自动化 家庭自动化一直是我们大多数人的灵感来源。从我们舒适的椅子或任何房间的床上切换交流负载,而无需伸手去触碰另一个房间的开关,听起来很酷,不是吗!.现在,在物联网时代,多亏了 ESP8266 模块,它使从世界…

【Java篇】一气化三清:类的实例化与封装的智慧之道

文章目录 类和对象&#xff08;中&#xff09;五、对象的构造及初始化5.1 如何初始化对象5.2 构造方法5.2.1 构造方法的概念5.2.2 构造方法的特性 5.3 默认初始化5.4 就地初始化 六、封装6.1 封装的概念6.2 访问限定符6.3 封装扩展之包6.3.1 包的概念6.3.3导入包6.3.3全类名6.3…