第2章 k-近邻算法【03】
实战3:手写识别系统
一、涉及的Python函数功能介绍:
1、readline()函数的作用
readline()只读取一行,并且内部指针会自动下移一行
readlines()读取所有行
不管是readline()还是readlines(),当读取完所有行内容后,若再次调用,则需要重新输入fr = open(filename) ,例如
fr = open('testData.txt')
否则读到的都是空,因为指针没有回到第一行
【注】引号不能漏!
详情:http://www.runoob.com/python/file-readline.html
二、实际操作
1、将图片转换为测试向量
1)在kNN.py内新增代码
#将图片转换为测试向量
def img2vector(filename):
returnVect = zeros((1,1024)) #一个样本有1024个特征
fr = open(filename) #打开具体文件
#逐行读取数据,共32行
for i in range(32):
#读取单独一行的内容,并且内部指针下移下一行
lineStr = fr.readline()
#读取每一行的第j的数据
for j in range(32):
#将每一行的第j的数据放进returnVect内
returnVect[0,32*i+j] = int(lineStr[j])
return returnVect
2)将testDigits文件夹和trainingDigits文件夹放在kNN.py的目录下,可在此处免费下载数据:http://www.ituring.com.cn/book/1021
(如果不介意施舍我2个积分的话也可以到这里。。。
http://download.csdn.net/download/weixin_38705903/10235455)
3)在kNN.py目录下打开cmd窗口 ([cmd窗口快速定位到具体文件夹方法][1])
然后输入以下代码
reload(kNN)
testVector = kNN.img2vector('testDigits/0_13.txt')
再次输入testVector[0,32:63]即可查看部分数据
2、使用kNN识别手写数字
1)在kNN.py内新增代码
from os import listdir
#使用kNN识别手写数字
def handwritingClassTest():
hwLabels = [] #用于存放所有label
trainingFileList = listdir('trainingDigits') #读取trainingDigits内所有文件的名字
m = len(trainingFileList) #得到样本数量m
trainingMat = zeros((m,1024)) #用于存放m个样本,1024个特征的数据
for i in range(m):
#提取label
fileNameStr = trainingFileList[i] #将第i个样本的文件名赋给fileNameStr
fileStr = fileNameStr.split('.')[0] #以.为依据切分名字,并且取前面的内容
#以_为依据切分名字,并且取前面的内容,即样本的label
classNumStr = int(fileStr.split('_')[0])
hwLabels.append(classNumStr) #将每次得到的label统一放入hwLabels
#提取data
#将trainingDigits文件夹内样本转化为向量并存放在trainingMat
trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
#读取testFileList内所有文件的名字
testFileList = listdir('testDigits')
errorCount = 0.0
mTest = len(testFileList) #得到测试集的样本数量mTest
for i in range(mTest):
#提取测试样本的label
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
#提取测试样本的data
vectorUnderTest = img2vector('testDigits/%s' % fileNameStr)
#测试
classifierResult = classify0(vectorUnderTest,\
trainingMat, hwLabels, 3)
print "the classifier came back with: %d, the real answer is: %d"\
% (classifierResult, classNumStr)
if (classifierResult != classNumStr): errorCount += 1.0
#返回测试结果
print "\nthe total number of errors is: %d" % errorCount
print "\nthe total error rate is: %f" % (errorCount/float(mTest))
2)在kNN.py目录下打开cmd窗口,然后输入
reload(kNN)
kNN.handwritingClassTest()
结果为:
the total number of errors is: 11
the total error rate is: 0.011628
三、常见错误
1、NameError:name ‘listdir’ is not defined
原因:要先从os模块中导入函数listdir才能使用
解决办法:在kNN.py开头加上
from os import listdir
若是想在cmd单独测试listdir(‘trainingDigits’),也需要在cmd窗口内重新输入from os import listdir,否则也会报错(kNN.py内的与cmd窗口无关)