机器学习——手写字符集

手写字符集

训练样本:trainingDigits

测试样本:testDigits

 用到的库:

#需要的库
from numpy import *
import numpy as np   #支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。
import operator      #提供了一系列的函数操作
from os import listdir        #Os库提供通用的、基本的操作系统交互功能
#数据处理:img2vector() :把一个测试/训练文件.txt转化为1个1行1024列的矩阵
def img2vector(filename):
    returnVect = np.zeros((1, 1024))
        # 创建1个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
#例如:
testVector = img2vector('testDigits/0_0.txt')
print(np.shape(testVector))  # (1, 1024)
print(testVector[0,0:31])
    # [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.]
##函数classfy0(),调用时传入classify0(vectorUnderTest当前测试文件(1×1024),trainingMat(训练总集合,m×1024),hwLabels,3)

tile()用法:python——numpy_jfoucti的博客-CSDN博客

def classify0(inX, dataSet, labels, k):  
    dataSetSize = dataSet.shape[0] 
        # shape()的功能是查看矩阵或者数组的维数,此处输出矩阵的行数,即m:文件个数
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet  
        # 传入dataSetSize=m
    sqDiffMat = diffMat ** 2 
        # 求幂
    sqDistances = sqDiffMat.sum(axis=1)  
        # axis=1就是将一个矩阵的每一行向量相加
    distances = sqDistances ** 0.5
    sortedDistIndicies = distances.argsort()  
        # argsort函数返回的是数组值从小到大的索引值
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]  
            # 取测试与训练最近的三(k)个
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1  
            # get()返回指定键的值,default=0——如果指定键的值不存在时,返回该默认值值0。
    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1),reverse=True)  
        # classCount.items()将classCount字典分解为元组列表,operator.itemgetter(1)按照第二个元素的次序对元组进行排序,reverse=True是逆序,即按照从大到小的顺序排列
        # 参考讲解:https://zhuanlan.zhihu.com/p/262568171
    return sortedClassCount[0][0]
#handWrithingClassTest():  
def handWrithingClassTest(): 
    hwLabels = []  # 创建标签列表
    trainingFileList = listdir('trainingDigits') 
        # listdir可以得到指定目录下的所有文件名,返回一个列表
    m = len(trainingFileList)  
        # 返回文件个数
    trainingMat = np.zeros((m, 1024))  
        # m行1024列的零矩阵
    for i in range(m):  # 获取训练样本的标签
        fileNameStr = trainingFileList[i]  
            #得到每个文件名称,如 “0_0.txt”
        fileStr = fileNameStr.split('.')[0] 
            # 把名字按.分成几个部分,装入列表,得到第[0]个部分,如0_0
        classNumStr = int(fileStr.split('_')[0])  
            # 按下划线分,取第一个元素为作为标签
        hwLabels.append(classNumStr)  
            # 将文件的标签加入标签列表
        trainingMat[i, :] = img2vector('trainingDigits/%s' % fileNameStr) 
            # 把每个训练样本存入矩阵,%s既代入fileNameStr
    errorCount = 0.0
        #错误个数
    testFileList = listdir('testDigits')  
        #获取所有测试样本
    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)  
            #将当前测试集存入矩阵1*1024
        classifierResult = classify0(vectorUnderTest,trainingMat,hwLabels,3) 
        print ("the classifier came back with: %d, the read answer is:%d" %(classifierResult,classNumStr) )
        if (classifierResult !=classNumStr):
            errorCount += 1.0


    '''
    ##该段注释代码将针对性输出判定结果,可自行选取样本进行测试
    TestMat = img2vector('testDigits/3_23.txt')
    fileNameStr = '3_23.txt'
        #此处选取3_23.txt,可换成其他测试数据
    fileStr = fileNameStr.split('.')[0]
    classNumStr = int(fileStr.split('_')[0])
    classifierResult = classify0(TestMat, trainingMat, hwLabels, 3)
    print("the classifier came back with: %d, the read answer is:%d" % (classifierResult, classNumStr))
    '''
    
    print("the total number of errors is %d" % errorCount)
    print("the total error rate is: %f" % (errorCount / float(mTest)))
handWrithingClassTest()

猜你喜欢

转载自blog.csdn.net/qq_58714269/article/details/126859835