项目案例: 手写数字识别系统

完整代码地址

项目概述

构造一个能识别数字 0 到 9 的基于 KNN 分类器的手写数字识别系统。
需要识别的数字是存储在文本文件中的具有相同的色彩和大小:宽高是 32 像素 * 32 像素的黑白图像。

开发流程

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

收集数据: 提供文本文件

压缩包 trainingDigits.zip 中包含了大约 2000 个例子,每个例子内容如下图所示,每个数字大约有 200 个样本;目录 testDigits 中包含了大约 900 个测试数据。下载后解压
手写数字数据集的例子

准备数据: 编写函数 img2vector(), 将图像文本数据转换为分类器使用的向量

将图像文本数据转换为向量

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

分析数据:在 Python 命令提示符中检查数据,确保它符合要求

在 Python 命令行中输入下列命令测试 img2vector 函数,然后与文本编辑器打开的文件进行比较:

  1. >>> testVector = kNN.img2vector('testDigits/0_13.txt')
  2. >>> testVector[0,0:32]
  3. array([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.])
  4. >>> testVector[0,32:64]
  5. array([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.])

训练算法:此步骤不适用于 KNN

因为测试数据每一次都要与全量的训练数据进行比较,所以这个过程是没有必要的。

测试算法:编写函数使用提供的部分数据集作为测试样本,如果预测分类与实际类别不同,则标记为一个错误

  1. def handwritingClassTest():
  2. # 1. 导入训练数据
  3. hwLabels = []
  4. trainingFileList = listdir('data/2.KNN/trainingDigits') # load the training set
  5. m = len(trainingFileList)
  6. trainingMat = zeros((m, 1024))
  7. # hwLabels存储0~9对应的index位置, trainingMat存放的每个位置对应的图片向量
  8. for i in range(m):
  9. fileNameStr = trainingFileList[i]
  10. fileStr = fileNameStr.split('.')[0] # take off .txt
  11. classNumStr = int(fileStr.split('_')[0])
  12. hwLabels.append(classNumStr)
  13. # 将 32*32的矩阵->1*1024的矩阵
  14. trainingMat[i, :] = img2vector('data/2.KNN/trainingDigits/%s' % fileNameStr)
  15. # 2. 导入测试数据
  16. testFileList = listdir('data/2.KNN/testDigits') # iterate through the test set
  17. errorCount = 0.0
  18. mTest = len(testFileList)
  19. for i in range(mTest):
  20. fileNameStr = testFileList[i]
  21. fileStr = fileNameStr.split('.')[0] # take off .txt
  22. classNumStr = int(fileStr.split('_')[0])
  23. vectorUnderTest = img2vector('data/2.KNN/testDigits/%s' % fileNameStr)
  24. classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
  25. print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr)
  26. if (classifierResult != classNumStr): errorCount += 1.0
  27. print "\nthe total number of errors is: %d" % errorCount
  28. print "\nthe total error rate is: %f" % (errorCount / float(mTest))

使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从图像中提取数字,并完成数字识别,美国的邮件分拣系统就是一个实际运行的类似系统。

本项目转载自:apachecn/AiLearning