在实现了K近邻算法后,书中给出了一个实例,今天来学习一下使用K近邻分类器的手写识别系统。书中原带的文件已经过处理转换为了文本格式,方便了许多。
先看一下原带文件
准备数据
#将图像转换为测试向量
def img2vector(filename):
returnVector = zeros((1,1024))#创建1*1024的数组,这样刚好能装下32*32的所有数据
fr = open(filename)
for i in range (32):
lineStr = fr.readline()#readline()将读取一行数据并返回,而readlines()函数将读取每一行数据,返回一个数组
for j in range (32):
returnVector[0,i*32+j] = lineStr[j]#这个循环很简单,将32*32的数据存储到1*1024数组中
return returnVector
程序清单2-6
#程序清单2-6手写数字识别系统的测试代码
def handwritingClassTest():
hwLabels = []
trainingFileList = listdir('F:\\机器学习\\MLiA_SourceCode\\machinelearninginaction\\Ch02\digits\\trainingDigits')#listdir()函数返回指定文件夹中所有文件的名称,以数组形式返回
m = len(trainingFileList)#得到文件个数,也即数据的个数
trainingMat = zeros((m,1024))#创建m行,1024列的零矩阵
for i in range(m):
fileNameStr = trainingFileList[i]#读取第i个文件的名称
fileStr = fileNameStr.split('.')[0]#split()函数将去除文件名中的'.',并返回分割后的字符串列表,索引0将读取第一个元素,根据源文件的命名规则,返回值是0_0,0_89,1_25等形式的字符串
classNumStr = int(fileStr.split('_')[0])#再次分割,并读取第一个元素,转化为整型,返回值是0,1,2,3...
hwLabels.append(classNumStr)#将最终得到的数值作为标签存储到列表中
trainingMat[i,:] = img2vector('F:\\机器学习\\MLiA_SourceCode\\machinelearninginaction\\Ch02\\digits\\trainingDigits\\%s' %fileNameStr)
#将指定文件转换为测试向量存储到trainingMat的第i行中,接下来对测试数据进行与前几步相似的处理
testFileList = listdir('F:\\机器学习\\MLiA_SourceCode\\machinelearninginaction\\Ch02\\digits\\testDigits')
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0]
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('F:\\机器学习\\MLiA_SourceCode\\machinelearninginaction\\Ch02\\digits\\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#当测试数据结果错误时,errorCount+1
print('\nthe total number of error is : %d' %errorCount )
print('\nthe total error rate is: %f' %(errorCount/float(mTest)))
OK了,接下来看一下运行结果
数据很多,跑起来着实有点烦人
错误率1.37%,很优秀~