文章目录

  • 手写识别系统
  • 步骤:
  • 准备数据:将图像转换为测试向量
  • 测试算法:使用k-近邻算法识别手写数字
  • 【完整代码】

手写识别系统

为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6。需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小[插图]:宽高是32像素×32像素的黑白图像。尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理解,我们还是将图像转换为文本格式。

步骤:

  1. 收集数据:提供文本文件。
  2. 准备数据:编写函数img2vector(),将图像格式转换为分类器使用的向量格式。
  3. 分析数据:在Python命令提示符中检查数据,确保它符合要求。
  4. 训练算法:此步骤不适用于k-近邻算法。
  5. 测试算法:编写函数使用提供的部分数据集作为测试样本,测试样本与非测试样本的区别在于测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
  6. 使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从图像中提取数字,并完成数字识别,美国的邮件分拣系统就是一个实际运行的类似系统。

准备数据:将图像转换为测试向量

实际图像存储在第2章源代码的两个子目录内:目录trainingDigits中包含了大约2000个例子,每个例子的内容如图2-6所示,每个数字大约有200个样本;目录testDigits中包含了大约900个测试数据。我们使用目录trainingDigits中的数据训练分类器,使用目录testDigits中的数据测试分类器的效果。两组数据没有重叠,你可以检查一下这些文件夹的文件是否符合要求。(【下载地址】
为了使用前面两个例子的分类器,我们必须将图像格式化处理为一个向量。我们将把一个32× 32的二进制图像矩阵转换为1×1024的向量,这样前两节使用的分类器就可以处理数字图像信息了。
我们首先编写一段函数img2vector,将图像转换为向量:该函数创建1×1024的NumPy数组,然后打开给定的文件,循环读出文件的前32行,并将每行的头32个字符值存储在NumPy数组中,最后返回数组。

def img2vector(filename):returnVect = zeros((1, 1024))fr = open(filename)for i in range(32):lineStr = fr.readline()for j in range(32):returnVect[0, 32 * i + j] = int(lineStr[j])return returnVect

进行测试:

testVector = img2vector('digits/testDigits/0_13.txt')
print(testVector[0, 0:31])
print(testVector[0, 32:63])
================================
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0.0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0.0. 0. 0. 0. 0. 0. 0.]

测试算法:使用k-近邻算法识别手写数字

函数handwritingClassTest()是测试分类器的代码,将其写入kNN.py文件中。在写入这些代码之前,我们必须确保将from os import listdir写入文件的起始部分,这段代码的主要功能是从os模块中导入函数listdir,它可以列出给定目录的文件名。

# 测试分类器
def handwritingClassTest():hwLabels = []# 获取目录内容trainingFileList = listdir('digits/trainingDigits')m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):# 从文件名解析分类数字fileNameStr = trainingFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])hwLabels.append(classNumStr)trainingMat[i, :] = img2vector('digits/trainingDigits/%s' % fileNameStr)testFileList = listdir('digits/testDigits')errorCount = 0.0mTest = len(testFileList)for i in range(mTest):fileNameStr = testFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])vectorUnderTest = img2vector('digits/testDigits/%s' % fileNameStr)classfierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)print("the classifier came back with %d, the real answer is %d" % (classfierResult, classNumStr))if (classfierResult != classNumStr): errorCount += 1.0print("\n the total number of errors is : %d" % errorCount)print("\n the total error rate is : %f" % (errorCount / float(mTest)))

将trainingDigits目录中的文件内容存储在列表中1,然后可以得到目录中有多少文件,并将其存储在变量m中。接着,代码创建一个m行1024列的训练矩阵,该矩阵的每行数据存储一个图像。我们可以从文件名中解析出分类数字2。该目录下的文件按照规则命名,如文件9_45.txt的分类是9,它是数字9的第45个实例。然后我们可以将类代码存储在hwLabels向量中,使用前面讨论的img2vector函数载入图像。在下一步中,我们对testDigits目录中的文件执行相似的操作,不同之处是我们并不将这个目录下的文件载入矩阵中,而是使用classify0()函数测试该目录下的每个文件。由于文件中的值已经在0和1之间,本节并不需要使用2.2节的autoNorm()函数。

测试:

handwritingClassTest()
=====================================
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
......
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9the total number of errors is : 10the total error rate is : 0.010571

k-近邻算法识别手写数字数据集,错误率为1.1%。改变变量k的值、修改函数handwriting-ClassTest随机选取训练样本、改变训练样本的数目,都会对k-近邻算法的错误率产生影响,感兴趣的话可以改变这些变量值,观察错误率的变化。
实际使用这个算法时,算法的执行效率并不高。因为算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,总计要执行900次,此外,我们还需要为测试向量准备2MB的存储空间。是否存在一种算法减少存储空间和计算时间的开销呢?k决策树就是k-近邻算法的优化版,可以节省大量的计算开销。

【完整代码】

from numpy import *
import operatordef classify0(inX, dataSet, labels, k):dataSetSize = dataSet.shape[0]# 距离计算diffMat = tile(inX, (dataSetSize, 1)) - dataSetsqDiffMat = diffMat ** 2sqDistances = sqDiffMat.sum(axis=1)distances = sqDistances ** 0.5sortedDistIndicies = distances.argsort()classCount = {}# 选择距离最小的k个点for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1# 排序sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]def autoNorm(dataSet):minVals = dataSet.min(0)maxVals = dataSet.max(0)ranges = maxVals - minValsnormDataSet = zeros(shape(dataSet))m = dataSet.shape[0]normDataSet = dataSet - tile(minVals, (m, 1))# 特征值相除normDataSet = normDataSet / tile(ranges, (m, 1))return normDataSet, ranges, minVals# 手写识别####################### 将图像转换为向量
def img2vector(filename):returnVect = zeros((1, 1024))fr = open(filename)for i in range(32):lineStr = fr.readline()for j in range(32):returnVect[0, 32 * i + j] = int(lineStr[j])return returnVect#
# testVector = img2vector('digits/testDigits/0_13.txt')
# print(testVector[0, 0:31])
# print(testVector[0, 32:63])from os import listdir# 测试分类器
def handwritingClassTest():hwLabels = []# 获取目录内容trainingFileList = listdir('digits/trainingDigits')m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):# 从文件名解析分类数字fileNameStr = trainingFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])hwLabels.append(classNumStr)trainingMat[i, :] = img2vector('digits/trainingDigits/%s' % fileNameStr)testFileList = listdir('digits/testDigits')errorCount = 0.0mTest = len(testFileList)for i in range(mTest):fileNameStr = testFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])vectorUnderTest = img2vector('digits/testDigits/%s' % fileNameStr)classfierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)print("the classifier came back with %d, the real answer is %d" % (classfierResult, classNumStr))if (classfierResult != classNumStr): errorCount += 1.0print("\n the total number of errors is : %d" % errorCount)print("\n the total error rate is : %f" % (errorCount / float(mTest)))handwritingClassTest()

【机器学习实战】k近邻算法实战——手写识别系统相关推荐

  1. 【Python】基于kNN算法的手写识别系统的实现与分类器测试

    基于kNN算法的手写识别系统 1.      数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...

  2. knn算法测试手写识别系统准确率

    手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...

  3. Knn算法之手写识别系统

    knn值之手写识别系统 导入包 import numpy as np from os import listdir import operator 介绍 1.os模块 os.listdir() 方法用 ...

  4. k近邻算法_图穷匕见:K近邻算法与手写数字识别

    机器学习算法是从数据中产生模型,也就是进行学习的算法.我们把经验提供给算法,它就能够根据经验数据产生模型.在面对新的情况时,模型就会为我们提供判断(预测)结果.例如,我们根据"个子高.腿长. ...

  5. 机器学习实战——2.3 示例:手写识别系统

    目录 1.准备数据:将图像转换为测试向量 2.测试算法:使用K-近邻算法识别手写数字 1.准备数据:将图像转换为测试向量 为了使用之前编辑好的classify0()分类器,我们必须将图像格式化处理为一 ...

  6. 机器学习实战-手写识别系统

    在实现了K近邻算法后,书中给出了一个实例,今天来学习一下使用K近邻分类器的手写识别系统.书中原带的文件已经过处理转换为了文本格式,方便了许多. 先看一下原带文件 准备数据 #将图像转换为测试向量 de ...

  7. java手写识别_手写识别系统

    目的 采用k-近邻算法实现手写识别系统.这里采用0和1组成数字0-9的形状,再用算法对这些形状进行识别,来分辨出形状属于0-9那个数字.并计算出k-近邻算法识别手写数字的错误率. 数据说明 数据来自& ...

  8. 机器学习之k近邻算法

    本文的代码基于书本<机器学习实战> 概念 k-近邻算法采用测量不同特征值之间距离的方法进行分类.工作原理是:存在一个样本数据集合,称作训练样本集,样本中每个数据都存在标签.输入没有标签的新 ...

  9. 机器学习算法(一):k-近邻理论与python实现+经典应用(约会网站匹配、手写识别系统)

    一份算法学习笔记~ 亲爱的朋友,恭喜你点开神秘之门,哈哈哈哈!从这里开始,我们一起学习机器学习的经典算法吧. 这一次的主要内容是机器学习入门算法:k-近邻.理论相当好理解,下面我们正式开始啦! 算法简 ...

最新文章

  1. - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
  2. 【剑指offer - C++/Java】8、跳台阶
  3. 【软件】OBS无法捕捉显示屏
  4. 包装类 与 简单集合框架
  5. sapi cli php mac,make: *** [sapi/cli/php] Error 1 解决办法
  6. django excel 导出页面_Django Admin中增加导出Excel功能过程解析
  7. SQL-92标准 中文翻译——定义、记号和约定 (记号)
  8. 你能在windows上创建一个叫做AUX的文件夹吗?
  9. Alfresco 4 项目介绍
  10. 安卓应用市场互相抓取app包
  11. 谈谈创业这点事 专业的盲区
  12. Stream流创建,常用方法
  13. python使用h5py读取mat文件数据
  14. PDF电子发票内容提取
  15. 这一篇说明大多数SQL优化的面试问题
  16. 哥尼斯堡的“七桥问题” (25分)
  17. 20210209PC版微信 网络不可用,请检查你的网络设置 的解决方法
  18. 如何用计算机名查看共享打印机,共享打印机怎么连接?打印机如何共享?查看图文帮你解决...
  19. iOS开发-技术知识盘点总结(二)
  20. 【IT软件专利】---专利编写步骤

热门文章

  1. Seq2Seq,Seq2Seq模型使用技巧
  2. zabbix监控windows磁盘读写速度
  3. Bookdown搭配GitHubPages发布电子书
  4. 照片误删了还能恢复吗?误删照片恢复教程
  5. Linux服务器定时器
  6. STM32在Keil中使用串口助手打印中文字符出现乱码问题
  7. MPR VTK 三维重建(二)multi-planner reformation 定位线 十字线
  8. 【ChatGPT对当代大学生的影响】
  9. Mockup的简单介绍
  10. 保定峻熙红帽linux认证