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

2018-10-17  本文已影响0人  梦vctor

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


image.png
image.png

该系统只能识别数字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-邻近算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外,由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时。其另外一个缺陷是无法给出任何数据的基本结构信息,因此也无法知晓平均实例样本和典型样本具有什么特征。而概率测量方法可以解决这个问题。

上一篇下一篇

猜你喜欢

热点阅读