一文实现0~9手写数字识别系统
上一篇《机器学习分类算法之k-近邻代码分析》中,大家后台留言有以下错误:
在此,统一给大家答复:这是由于Python 3与Python 2之间的割裂以及向下不兼容造成的,iteritems是Python2里的写法,Python3中使用items。出错的童鞋使用的环境是Python3,大家可以查看下自己的Python版本。
后续的代码分享,均使用Python3,如果有Python2和Python3不一致的地方,我会做好标注。
修改后正确的运行结果,如下:
本节分享的是Peter机器学习实战中2.3示例手写识别系统。怎样一步步构建并使用k-近邻分类器进行数字0~9的手写识别。
这个图应该不陌生,是经典的识别数字的卷积网络LeNet-5。通过简单的图像处理(处理的都是小patchs,比如28*28或32*32、图像归一化等操作,将像素数据送入卷积网络训练。
Peter机器学习从数据机器学习角度给了另一种实现手写识别的思路,作为识别数字的入门实现思路之一,还是不错的。也能很好的说明k-近邻分类器的用途。
按照掌握的k-近邻的实现路线,实现手写数字识别大致需要以下过程:
(1)收集数据:图像数据转化成文本数据(虽然文本格式存储图像不能利用内存空间,但是为了方便理解,还是转成文本格式,本文中图像大小采用32*32)
(2)准备数据:编写classify0()函数,将图像格式转换为分类器使用的list格式。另,数据需要分为两部分,一部分作为测试样本,另一部分作为非测试样本,非测试样本是已经完成分类的数据。
(3)分析数据:检查数据,确保数据符合要求。
(4)测试算法:用已知分类的数据和classify0()去测试分类结果与已知分类是否一致
(5)使用算法:从图像中提取数字,并完成数字识别。(此过程《机器学习实战》中没有)
收集数据:将图像转换为测试向
为了方便,直接使用2.3示例中提供的数据,数据情况如下:
数据目录
图像数据:如0,2
为了直接使用上一篇中的createDataSet()和classify0(),将每个32*32的二进制图像矩阵转化为1*1024向量。
需要定义函数img2vector,原理比较简单,循环读出32行,写入数字。下面以trainingDigits里的0_0.txt为例:
测试算法
该过程使用classify0()计算某个图像数据向量与一堆向量哪个向量最相近,便将最相近向量对应的标签作为该图像数据的标签。
算法测试原理:用trainingDigits里的数据做验证,该数据集里的命名方式"数字_该数字第几个实例.txt"。用classify0()测试trainingDigits下每一个数据是否正确。因为要遍历整个数据集文件目录,所以需要引入listdir函数(from os import listdir)。代码由三部分构成,分别是获取trainingDigits的文件目录内容、从文件名中解析出分类数字、classify0()识别出每个文件的分类数字。
代码实现
结果
PS:该过程又出现了Python3和Python2的不同之处:print。
python3中print是一个内置函数,有多个参数,而python2中print是一个语法结构;Python2打印时可以不加括号:print 'hello world', Python3则需要加括号 print("hello world")。
使用算法(该部分书本中没有)
写了一个简单的函数useClassify(filename),供大家参考,下面是函数实现:
小编自己从一副二值化的32*32的图像(数字0)转化为文本格式的数据,拿来做算法使用测试,测试结果如下:
总结:
数据量大了后,算法的执行效率不高,一是因为占用存储空间,另一个是已知分类数据多的情况下,耗时也会增长。再有k-近邻的原理导致没办法使用表征数据更好的特征。
理财快讯:如果你没能赶上打新股,那就参与打新债吧!
欢迎转发到朋友圈或分享给好友