zoukankan      html  css  js  c++  java
  • 机器学习实战学习笔记(二)-KNN算法(2)-使用KNN算法进行手写数字的识别

    机器学习实战学习笔记(二)-KNN算法(2)-使用KNN算法进行手写数字的识别

    概要

    目的

    构造使用k-近邻分类器的手写识别系统。为了简单起见,这里构造只能识别数字0到9分类器

    数据格式

    文件名包含了标签

    内部是图片转化成的txt格式

    步骤

    图像转化为测试向量

    必须将图像格式化处理为一个向量。 我们将把一个32 x32的二进制图像矩阵转换为1 x 1024的向量,这样前两节使用的分类器就可以处理数字图像信息了.

    # 打开文件
    def imgvector(filename):
        returnVect=np.zeros((1,1024))
        fr=open(filename,'r',encoding='utf-8')
        for i in range(32):
            lineStr=fr.readline()
            for j in range(32):
                returnVect[0,32*i+j]=int(lineStr[j])
        return returnVect
    

    测试算法

    1.获取目录的内容
    2.读取目录的文件名因为它包含了分类的标签
    3.读取每张图片(txt文档)的向量
    4.读取测试集,进行训练,输出结果
    5.统计最终结果

    # 手写测试
    def handwritingClassTest():
        hwLabels=[]
        trainingFileList=listdir('KNN/testDigits')
        m=len(trainingFileList)
        trainingMat=np.zeros((m,1024))
        for i in range(m):
            filenameStr=trainingFileList[i]
            fileStr=filenameStr.split('.')[0]
            classNumStr=int(fileStr.split('_')[0])
            hwLabels.append(classNumStr)
            trainingMat[i,:]=imgvector('KNN/testDigits/%s'%filenameStr)
        testFileList=listdir('KNN/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=imgvector('KNN/testDigits/%s'%filenameStr)
            classifierResult=knnClassify(vectorUnderTest,trainingMat,hwLabels,3)
            print("分类器的返回结果是%d,真正的结果是%s"%(classifierResult,classNumStr))
            if classifierResult!=classNumStr:
                errorCount+=1.0
        print("总预测错误的次数为: %d "%errorCount)
        print("总的错误率为 %f "%(errorCount/float(mTest)))
    
    

    结果

    我的做法是错误的,不可以使用训练接作为测试集!!!,但是还是记录下吧!

    附录代码

    import numpy as np
    from os import listdir 
    import operator as op
    
    #K近邻算法
    #inX是输入的数据
    #dataSet是训练的数据
    #labels是标签,类别
    #k是周围邻居的数量
    #返回预测的类别
    def knnClassify(inX,dataSet,labels,k):
        #计算欧式距离
        dataSetSize=dataSet.shape[0]#shape是(4,2),要获取点的数量显然是shape[0]
        diffMat=np.tile(inX,(dataSetSize,1))-dataSet
        '''
        np.tile(inX,(dataSetSize,1))=[[0,0],[0,0],[0,0],[0,0]]
        dataSet=[[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]
        np.tile-dataSet=[[-1.0,-1.1],[-1.0,-1.0],[0,0],[0,-0.1]]
        即([x1-x0,y1-y0],[x2-x0,y2-x0],[x3-x0,y3-y0],[x4-x0,y4-y0])
        '''
        sqdiffMat=diffMat**2
        #([(x1-x0)**2,(y1-y0)**2],[(x2-x0)**2,(y2-x0)**2],[(x3-x0)**2,(y3-y0)**2],[(x4-x0)**2,(y4-y0)**2])
        sqDistances=sqdiffMat.sum(axis=1)
        #([(x1-x0)**2+y1-y0)**2],[(x2-x0)**2+(y2-x0)**2],[(x3-x0)**2+(y3-y0)**2],[(x4-x0)**2+(y4-y0)**2])
        # print(sqDistances)
        distances=sqDistances**0.5
        #([(x1-x0)**2+(y1-y0)**2]**(0.5),[(x2-x0)**2+(y2-x0)**2]**(0.5),[(x3-x0)**2+(y3-y0)**2]**(0.5),[(x4-x0)**2+(y4-y0)**2])**(0.5)
        sortedDistIndicies=distances.argsort()#按照数值大小对下标排序,[2 3 1 0]
        classCount={}
        #选择距离最小的k个点
        for i in range(k):
            votIlabel=labels[sortedDistIndicies[i]]#获取最近的K个邻居的距离,对应的目标值
            # print(votIlabel)
            classCount[votIlabel]=classCount.get(votIlabel,0)+1#get(key,default)当key不存在时候默认值是default
        sortedClassCount = sorted(classCount.items(), key=op.itemgetter(1), reverse=True)
        # [('B', 2), ('A', 1)]
        return sortedClassCount[0][0]#返回与其最近的k个邻居中,出现最多的次数
    
    
    
    # 打开文件
    def imgvector(filename):
        returnVect=np.zeros((1,1024))
        fr=open(filename,'r',encoding='utf-8')
        for i in range(32):
            lineStr=fr.readline()
            for j in range(32):
                returnVect[0,32*i+j]=int(lineStr[j])
        return returnVect
    
    # 手写测试
    def handwritingClassTest():
        hwLabels=[]
        trainingFileList=listdir('KNN/testDigits')
        m=len(trainingFileList)
        trainingMat=np.zeros((m,1024))
        for i in range(m):
            filenameStr=trainingFileList[i]
            fileStr=filenameStr.split('.')[0]
            classNumStr=int(fileStr.split('_')[0])
            hwLabels.append(classNumStr)
            trainingMat[i,:]=imgvector('KNN/testDigits/%s'%filenameStr)
        testFileList=listdir('KNN/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=imgvector('KNN/testDigits/%s'%filenameStr)
            classifierResult=knnClassify(vectorUnderTest,trainingMat,hwLabels,3)
            print("分类器的返回结果是%d,真正的结果是%s"%(classifierResult,classNumStr))
            if classifierResult!=classNumStr:
                errorCount+=1.0
        print("总预测错误的次数为: %d "%errorCount)
        print("总的错误率为 %f "%(errorCount/float(mTest)))
    
    
    
    if __name__ == "__main__":
        handwritingClassTest()
    
    

    目录结构

    数据集地址

    https://github.com/pbharrin/machinelearninginaction

    参考书籍

    <<机器学习实战>>

  • 相关阅读:
    Docker部署
    编写一个脚本用户进入容器
    Shell脚本写的《俄罗斯方块》
    Linux磁盘分区(9)
    Linux任务调度(8)
    Linux权限管理(7)
    Linux组管理(6)
    Linux实用指令(5)
    C#中 char、byte、string
    编码转换
  • 原文地址:https://www.cnblogs.com/mengxiaoleng/p/12236075.html
Copyright © 2011-2022 走看看