基于K-近邻算法的手写数字识别研究

摘要:基于K-近邻算法研究手写数字(0-9)的识别问题,本文通过对手写数字的图像进行处理,提取特征向量,使用Python实现了K-近邻算法,并在此基础上开发了一个GUI测试程序,不仅能够实时测试手写识别的结果和调整k值,而且能够对识别错误的数字进行更正,将其加入训练库,使得该程序具有持续的学习能力,不断提高识别精度。

1.引言

          K-近邻算法是数据分类中最简单有效的算法。通过计算未知样本与已知样本之间的距离,找出离未知样本最近的已知样本,并将该样本的类别赋予未知样本,即实现了对未知样本的分类。其中,样本之间的距离是通过对样本的特征向量进行计算得出的,每个样本在特征空间中是一个点,则只需在特征空间中计算的两点距离就能计算出两个样本之间的距离,距离越小,则说明两个样本之间越相似。在选择最近样本时,如果选择的不止一个,例如k个,则称为k-近邻,此时未知样本分类的准则为:在k个最近的样本中,将出现次数最多的样本所属的类别赋予未知样本,即完成未知样本的分类。

      在本文中,首先使用python实现了一个k-近邻算法,能够对任意的样本进行k-近邻分类。然后研究了图像特征参数的提取,即从每副图像中提取特征向量用于分类算法。使用该方法对大量的样本进行研究,研究不同k值情况下的分类精度问题,最后使用该算法实现一个手写数字识别演示软件。

2.K-近邻算法实现

K-近邻算法实现较为简单,其主要过程如下:

1)计算已知类别数据集中的点与当前点之间的距离;

2)按距离递增次数排序;

3)选取与当前点距离最小的k个点;

4)确定当前k个点所在的类别的出现频率;

5)返回前k个点中出现频率最高的点所属的类作为当前点的预测分类。

Python代码实现如下(使用python下的科学计算库numpy):
def knn_classify(inX,dataSet,labels,k):
    '''
    knn算法
    inX 待分类向量
    dataSet 训练样本
    labels 标签向量
    k 最邻近元素的个数
    '''
    dataSetSize = dataSet.shape[0]  #numpy用法 获取训练样本数据的维度大小
    diffMat = tile(inX,(dataSetSize,1))-dataSet #将inX扩展为跟dataSet维数相同进行相减
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5       #上三步用于计算欧式距离
    sortedDistIndicies = distances.argsort()  #按Distance从小到大排序 此处记录的是下标
    classCount={}
    for i in range(k):   #取前k个
        votelabel=labels[sortedDistIndicies[i]]
        classCount[votelabel]=classCount.get(votelabel,0)+1  #记录每个类别在最近的k个中出现了几个  例如 dict: {'A': 1, 'B': 2}
    sortedClassCount = sorted(classCount.iteritems(),
                                  key=operator.itemgetter(1),reverse=True)#按 value字段排列字典 
    return sortedClassCount[0][0]  #返回所属类别

3.图像特征向量提取

  为了将图像能够表示成特征向量,首先需要对0-9这10个数字的图像进行二值化,背景值为10,并且统一大小,在此处使用32×32像素,最后将该图像保存成txt格式方便调用。下图给出了两个例子:

        

图1 图像二值化后生产的txt文档格式

    由于二值化后的图像仍然是二维数组的形式,因此考虑将其转化为一维形式,即1*1024维的数组,每个像素的值就是1024维特征空间的一个坐标轴的值,这样一幅图像就能够表示成特征空间中的点,而k-近邻分类算法就是要对这些点的距离进行计算。

4.手写识别软件的实现

  在K-近邻算法的基础上,本文实现了一个带有GUI界面的程序,能够通过鼠标进行绘制数字,然后通过训练样本进行识别。

  GUI程序使用Python库wxPython编写,并且通过pyinstaller进行编译,将py脚本文件编译成exe可执行文件,在没有安装python的计算机上也能够执行。UI界面如下:

                         

                                图2  手写识别GUI界面

   图2中的红色部分是绘制数字的区域,通过鼠标进行绘制,数字大小最好能够填满整个红色部分。

【清空】表示对红色部分进行清空;

【识别】表示对绘制的数字进行识别,识别的结果会写在按钮下边的长文本框中;

【最邻近点个数】即k值,表示在选择最近点时,选择多少个进行位置样本的分类决策’

【输入正确的值并更正】表示当识别错误时,可以选择输入一个正确的值,然后点击更正,将该样本加入训练库中,表示软件对手写的学习,在下一次识别过程中能够提高识别精度。

使用例子:例如,在红色区域绘制一个3后,通过点击识别,即能够将识别结果写在按钮下边的文本框中;若本来绘制的是5,而被错误地识别为3,则可通过在【输入正确的值并更正】处填上5,并点击更正按钮,则该结果会作为正确的分类进入训练样本库中。

 

 

图3 使用举例

  软件识别过程中通过对鼠标在红色画布上的移动,记录鼠标的坐标信息,并将其所到之处及周围(线宽)像素设置为1,即完成了测试样本的处理。获取测试样本之后,将该样本与训练样本进行比较,使用k-近邻算法,找出该样本的分类,最后输出该样本的分类结果。

总结:

  分类精度评价来看,k近邻分类分类效果总体还是比较好的,正确率能够到98%以上,但是,运用于实际场景中,由于未知样本变化太多,不确定性太强,很多时候效果并不令人满意。

代码链接:

手写数字识别Python代码



  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
基于Matlab的手写数字识别是一种利用计算机视觉技术和机器学习算法,对手写数字进行图像处理和特征提取,进而实现自动识别的方法。以下是基于Matlab的手写数字识别的工作流程: 首先,收集大量的手写数字图像作为训练数据集,这些图像需要包含各种不同写法和风格的数字。然后,将这些图像转换为灰度图像,以减少计算量。 接着,进行图像预处理,包括降噪、图像增强等。常用的方法有中值滤波、高斯滤波、直方图均衡化等。这些处理方法可以减少图像中的噪声和干扰。 然后,使用特征提取算法从预处理后的图像中提取数字的特征。常用的特征提取方法有方向梯度直方图(HOG)、局部二值模式(LBP)等。这些特征可以表征数字的形状、纹理等特征。 在特征提取完成后,使用机器学习算法进行数字的分类与识别。常用的算法有支持向量机(SVM)、K近邻算法(KNN)等。首先,将数据集分为训练集和测试集。然后,使用训练集对分类器进行训练,调整参数并优化模型。最后,在测试集上评估分类器的性能,计算准确率、召回率等指标。 最后,将训练好的模型应用于新的手写数字图像,通过比对特征和分类器的预测结果,实现手写数字的自动识别。 基于Matlab的手写数字识别非常灵活和高效,通过调用Matlab强大的图像处理和机器学习工具箱,可以快速搭建和实现手写数字识别系统。此外,Matlab还提供了可视化工具和分析函数,方便对识别结果进行可视化和统计分析。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

倾城一少

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值