k-邻近算法的手写识别系统


该系统只能识别数字0-9,图像转换成为了文本的若干文本数据
准备数据
#将图像转换为测试向量
def img2vector(filename):
returnVect=zeros((1,1024)) #把一个32*32的二进制图像矩阵转换为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
Debug:
FileNotFoundError: [Errno 2] No such file or directory: 'testDigits/0_13.txt'
解决方案:
将下载的源数据中的testDigits文件添加到工作空间位置
#代码输出:
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.]
测试算法
#from os import listdir写到文件起始部分,其主要功能是从os模块中导入函数listdir,它可以列出给定目录的文件名
#手写数字识别系统的测试代码
def handwritingClassTest():
hwLabels=[]
#将trainingDigits目录中的文件内容存储到列表中
trainingFileList=listdir('trainingDigits')
#目录中的文件数量m
m=len(trainingFileList)
#创建一个m行1024列的训练矩阵,每行数据存储一个图像
trainingMat=zeros((m,1024))
for i in range(m):
#解析分类数字
fileNameStr=trainingFileList[i]
fileStr=fileNameStr.split('.')[0]
classNumStr=int(fileStr.split('_')[0])
#将类代码存储在hwLabels中
hwLabels.append(classNumStr)
#载入图像
trainingMat[i,:]=img2vector('trainingDigits/%s' % fileNameStr)
#对testDigits目录中文件执行相似的操作
testFileList=listdir('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('testDigits/%s' % fileNameStr)
#用classify0()函数测试该目录下的每个文件
classifierResult=classify0(vectorUnderTest,trainingMat,hwLabels,3)
print("the classifier came back with:%d,the real anwser 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)))
#代码输出:
print(KNN.handwritingClassTest())
Debug1:
FileNotFoundError: [WinError 3] 系统找不到指定的路径。: 'trainingDigits'
解决方法:
将下载的源数据中的trainingDigits文件添加到工作空间位置
Debug2:
TypeError: not all arguments converted during string formatting
解决方法:
将print("\nthe total error rate is :%f" % (errorCount/float(mTest)))中的&改为%。
输出:
the classifier came back with:9,the real anwser is :0
the classifier came back with:9,the real anwser is :0
......
the classifier came back with:9,the real anwser is :9
the classifier came back with:9,the real anwser is :9
the total number of errors is :10
the total error rate is :0.010571
改变变量k的值、修改函数handwritingClassTest随机选取训练样本、改变训练样本的数目,都会对k-邻近算法的错误率产生影响。
实际该算法的执行效率并不高。k决策树是k-邻近算法的优化版,可以节省大量的计算开销。
本章小结
k-邻近算法是分类数据最简单最有效的算法。使用算法时必须有接近实际数据的训练样本数据。k-邻近算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外,由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时。其另外一个缺陷是无法给出任何数据的基本结构信息,因此也无法知晓平均实例样本和典型样本具有什么特征。而概率测量方法可以解决这个问题。
网友评论