基于Python实现手写数字识别

news2025/4/21 20:25:12

KNN实验——手写数字识别

实验目的:

实验内容:

  1. 实现最基本的KNN算法,使用trainingDigits文件夹下的数据,对testDigits中的数据进行预测。(K赋值为1,使用欧氏距离,多数投票决定分类结果)
  2. 改变K的值,并观察对正确率的影响。
  3. 更改距离度量方式,更改投票方式(距离加权),分析错误率。

实验要求:

  1. 要求给出代码,以及运行窗口截图。
  2. 对正确率的影响,最好用表格或作图说明,并做简要分析。
  3. 实验内容3为选做,不做统一要求。

实验步骤与内容:

算法设计说明

实验环境

  1. 硬件环境    个人笔记本电脑
  2. 软件环境    Python   Eclipse  Pydev插件

所用语言:Python

实验数据分析

把来自UCI数据库的手写数据集简化成32像素x32像素的黑白图像,并且以01矩阵的方式存储在txt文件中。大约有训练样本2000个,测试样本900个。

digits 目录下有两个文件夹,分别是:

  1. trainingDigits:训练数据,1934个文件,每个数字大约200个文件。
  2. testDigits:测试数据,946个文件,每个数字大约100个文件。

每个文件中存储一个手写的数字,文件的命名类似0_7.txt,第一个数字0表示文件中的手写数字是0,后面的7是个序号。

我们使用目录trainingDigits中的数据训练分类器,使用目录testDigits中的数据测试分类器的效果。两组数据没有重叠。

算法设计

1.思路

  1. KNN的主要思想是找到与待测样本最接近的k个样本,然后把这k个样本出现次数最多的类别作为待测样本的类别。
  2. 下载实验要求中给的数据集digits文件夹,用trainingDigits作训练集,用testDigits作为测试集
  3. 将每个样本的txt文件转换为对应的一个向量
  4. 以欧氏距离作为度量进行KNN算法,分析样本之间的相似度

2.具体实现

a.加载数据loadDataSet():

从digits文件夹中读取训练数据和测试数据

以训练数据为例

dataSetDir = './digits/'     
trainingFileList = os.listdir(dataSetDir + 'trainingDigits')

加载同目录下/digits/trainingDigits中的训练数据文件

numSamples = len(trainingFileList)
train_x = zeros((numSamples, 1024))
train_y = []

train_x用来储存txt文件转换成的向量

train_y用来储存该文件实际代表的数字

for i in xrange(numSamples):
        filename = trainingFileList[i]
       对每个训练数据文件进行处理
        # get train_x
        train_x[i, :] = img2vector(dataSetDir + 'trainingDigits/%s' % filename)
        调用img2vector方法将txt文件转换为对应的一个向量
        # get label from file name such as "1_18.txt"
        label = int(filename.split('_')[0]) # return 1
        train_y.append(label)
  记录该文件实际代表的数字

加载测试集数据的过程同理,用test_x,test_y表示

b.将图片转换为向量img2vector(filename):

def  img2vector(filename):
    rows = 32
    cols = 32

数据的行列都是32

imgVector = zeros((1, rows * cols))
fileIn = open(filename)

对每个训练数据文件进行处理

  for row in xrange(rows):
        lineStr = fileIn.readline()
        for col in xrange(cols):
            imgVector[0, row * 32 + col] = int(lineStr[col])
return imgVector

转换为向量

c.KNN分类核心方法 kNNClassify(newInput, dataSet, labels, k):

newInput为待测试数据,dataSet是训练集,labels是分类合集

def kNNClassify(newInput, dataSet, labels, k):
numSamples = dataSet.shape[0]  # shape[0]代表行数

已知分类的数据集(训练集)的行数

先tile函数将输入点拓展成与训练集相同维数的矩阵,再计算欧氏距离

 # # step 1: 计算欧式距离
    # tile(A, reps): 将A重复reps次来构造一个矩阵
    # the following copy numSamples rows for dataSet
diff = tile(newInput, (numSamples, 1)) - dataSet  # Subtract element-wise
    样本与训练集的差值矩阵
squaredDiff = diff ** 2  # squared for the subtract
差值矩阵平方
squaredDist = sum(squaredDiff, axis = 1)   # sum is performed by row
计算每一行上元素的和
distance = squaredDist ** 0.5
    开方得到欧拉距离矩阵

    # # step 2: 对距离排序
    # argsort()返回排序后的索引
sortedDistIndices = argsort(distance)
    按distances中元素进行升序排序后得到的对应下标的列表
    classCount = {}  # 定义一个空的字典
    for i in xrange(k):
        # # step 3: 选择k个最小距离
        voteLabel = labels[sortedDistIndices[i]]
        # # step 4: 计算类别的出现次数
        # when the key voteLabel is not in dictionary classCount, get()
        # will return 0
        classCount[voteLabel] = classCount.get(voteLabel, 0) + 1
    选择距离最小的k个点
    # # step 5: 返回出现次数最多的类别作为分类结果
    maxCount = 0
    for key, value in classCount.items():
        if value > maxCount:
            maxCount = value
            maxIndex = key
    return maxIndex
返回出现次数最多的类别作为分类结果

d.计算预测准确率

# # step 3: 测试
    print "step 3: testing..."
    numTestSamples = test_x.shape[0]
matchCount = 0
声明总待测数据和预测正确数
    for i in xrange(numTestSamples):
        predict = kNNClassify(test_x[i], train_x, train_y, 1)
        if predict == test_y[i]:
            matchCount += 1
    对每一个测试样本进行测试,正确则计入
    accuracy = float(matchCount) / numTestSamples
   计算正确率

3.改进

程序运行结果仅输出几个步骤提示,界面停滞几分钟后便直接输出准确率的结果,未免有些不到位,所以应该加入更加细致的算法运行结果的显示。

需要添加:

对每个测试样本进行KNN分类算法后的结果

与该样本实际类别的比较

print "分类结果为: %d, 实际类别为: %d" % (predict, test_y)

总测试数量
print "总测试样本数: %d" % numTestSamples
测试准确数
print "测试正确样本数: %d" % matchCount
分类准确率
print '分类正确率: %.2f%%' % (accuracy * 100)

实验结果

要求:改变K的值,并观察对正确率的影响。

K值

正确率

1

98.63%

2

98.63%

3

98.84%

4

98.52%

5

98.20%

实验结果分析:

根据上方的图表,可以看出K的取值可以影响分类的准确率

K=1时准确率就已经高达98.63%;K=2时准确率保持不变,仍是98.63%;在K=3的时候准确率最高,上升到了98.84%;在K=4时又开始降低到98.52%;K=5时准确率仍然在降低,为98.20%

之后增加K的值,如K=6,K=7,可以看到准确率继续降低

结论是,为了保证较高的准确率,应该把K的值设得小一些。

实验结果截图

K=1

K=2

结果同K=1

K=3

K=4

K=5

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

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

相关文章

shell的模拟实现 ─── linux第16课

目录 第一版只能维护命令行参数表创建子进程, 执行非内建命令 第一版的执行结果: 第二版能维护命令行参数表执行cd命令 ,判断了是否是自建命令(mysell自己执行自建命令,可以对环境变量发生改变),子进程执行其他命令. 第二版执行结果: 第三版 模拟真实shell从系统文件中获取环…

游戏引擎学习第153天

仓库:https://gitee.com/mrxiao_com/2d_game_3 回顾 目前正在进行的是一个比较大的系统调整,原本预计今天会继续深入这个改动,但实际上在昨天的开发中,我们已经完成了大部分的代码编写,并且运行之后几乎一切都能正常工作&#x…

Java EE 进阶:SpringBoot 配置⽂件

什么是配置文件 “配置文件”是一个用来保护程序或者系统设置信息的文件,它的作用是让程序在启动或者运行中,能够读取这些设置并按预期进行工作,而不需要手动的设置。 Spring Boot 配置文件 设置服务器端口、编码格式配置数据库连接控制日…

【redis】五种数据类型和编码方式

文章目录 五种数据类型编码方式stringhashlistsetzset查询内部编码 五种数据类型 字符串:Java 中的 String哈希:Java 中的 HashMap列表:Java 中的 List集合:Java 中的 Set有序集合:除了存 member 之外,还有…

色板在数据可视化中的创新应用

色板在数据可视化中的创新应用:基于色彩感知理论的优化实践 引言 在数据可视化领域,色彩编码系统的设计已成为决定信息传递效能的核心要素。根据《Nature》期刊2024年发布的视觉认知研究,人类大脑对色彩的识别速度比形状快40%,色…

【无人机路径规划】基于麻雀搜索算法(SSA)的无人机路径规划(Matlab)

效果一览 代码获取私信博主基于麻雀搜索算法(SSA)的无人机路径规划(Matlab) 一、算法背景与核心思想 麻雀搜索算法(Sparrow Search Algorithm, SSA)是一种受麻雀群体觅食行为启发的元启发式算法&#xff0…

STM32_GPIO系统外设学习

按照STM32MCUWIKI、参考手册的外设介绍----->CubeF4的软件包中相关的Exmple代码----->CubeMX设置截图加深理解记忆 资料链接:嵌入式开发_硬软件的环境搭建 我的飞书文档-GPIO篇 如果觉得内容不错,欢迎给我的飞书文档点赞。同时如果有什么意见或…

【操作系统安全】任务1:操作系统部署

目录 一、VMware Workstation Pro 17 部署 二、VMware Workstation 联网方式 三、VMware 虚拟机安装流程 四、操作系统介绍 五、Kali 操作系统安装 六、Windows 系统安装 七、Windows 系统网络配置 八、Linux 网络配置 CSDN 原创主页:不羁https://blog.csd…

下载安装启动 VMware 个人免费版本

一、进入官网并登录账号下载软件 进入官网 [ https://www.vmware.com ],点击Products,将页面划到最底下,点击 “SEE DESKTOP HYPERVISORS”按钮。 然后点击 Desktop hypevisor ,会出现如下界面,可以根据自己的操作系…

C#+AForge 实现视频录制

C#AForge 实现视频录制 ​ 在C#中,使用AForge 库实现视频录制功能是一个比较直接的过程。AForge 是一个开源的.NET框架,提供了许多用于处理图像和视频的类库。 开发步骤 安装AForge库 ​ 首先,确保你的项目中已经安装了 AForge.Video和AFo…

SAP SD学习笔记31 - 销售BOM

上一篇讲 前受金处理(预付款处理)。 SAP SD学习笔记29 - 前受金处理(预收款处理)_fplt 付款申请与sd 数据表的关联关系-CSDN博客 本章继续讲SAP SD模块的其他知识:销售BOM。 销售BOM在现场还是会用到的。 目录 1,销售BOM概要 2,受注BOM的…

大数据学习(63)- Zookeeper详解

&&大数据学习&& 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言📝支持一下博主哦🤞 &#x1f…

嵌入式八股C语言---面向对象篇

面向对象与面向过程 面向过程 就是把整个业务逻辑分成多个步骤,每步或每一个功能都可以使用一个函数来实现面向对象 对象是类的实例化,此时一个类就内部有属性和相应的方法 封装 在C语言里实现封装就是实现一个结构体,里面包括的成员变量和函数指针,然后在构造函数中,为结构体…

C# ListView设置标题头背景颜色和字体颜色

一、向ListView 添加数据 for (int i 1; i < 5; i) {ListViewItem litem new ListViewItem("data:"i);lv_WarnList.Items.Add(litem); }如果需要在ListView中绑定实体类对象的话&#xff0c;需要将数据放在Tag属性里 for (int i 1; i < 5; i) {AngleData …

嵌入式 ARM Linux 系统构成(6):应用层(Application Layer)

目录 一、应用层概述 二、应用层的核心组成 2.1 主应用程序&#xff08;Main Applications&#xff09; 2.2 系统服务&#xff08;System Services&#xff09; 2.3 用户界面&#xff08;User Interface&#xff09; 2.4 脚本与自动化工具 2.5 第三方库与框架 2.6 通信…

【HTML】一、基础标签

文章目录 1、开发环境准备2、html介绍3、html基本骨架4、标签的关系5、常用标签5.1 标题5.2 段落5.3 换行与水平线5.4 文本格式化标签5.5 图像标签5.6 超链接标签5.7 音频标签5.8 视频标签 6、路径7、网页制作 1、开发环境准备 在编辑器中写代码&#xff0c;在浏览器中看效果 …

centos7通过yum安装redis

centos7通过yum安装redis 1.安装redis数据库 yum install -y redis2.启动redis服务 systemctl start redis3.查看redis状态 systemctl status redis4、停止服务 systemctl stop redis5、重启服务 systemctl restart redis6、查看redis进程 ps -ef | grep redis7、开放端…

AutoMQ x OSS 的 Iceberg 数据入湖的最佳实践

背景 在数字化转型进程中&#xff0c;用户交互行为产生的多维度数据已成为企业的重要战略资产。以短视频平台为例&#xff0c;基于用户点赞事件的实时推荐算法能显著提升用户活跃度和平台粘性。这类实时数据主要通过 Apache Kafka 流处理平台进行传输&#xff0c;通过其扇出&a…

【Help Manual】导出PDF中英文不在一行解决方案

在使用Help Manual 的时候&#xff0c;会出现导出PDF时&#xff0c;中英文在同一行出现水平不对齐的问题。如下&#xff1a; 解决方案&#xff1a; 结果如下&#xff1a;

Scala编程_实现Rational的基本操作

在Scala中实现一个简单的有理数&#xff08;Rational&#xff09;类&#xff0c;并对其进行加法、比较等基本操作. 有理数的定义 有理数是可以表示为两个整数的比值的数&#xff0c;通常形式为 n / d&#xff0c;其中 n 是分子&#xff0c;d 是分母。为了确保我们的有理数始终…