机器学习实战实例练习-手写识别系统

本文内容以代码为主(详细请参考<机器学习实战>书籍),主要用于自读回顾,故注释未精简化,若发现错误还望各位前辈批评指正.

先展示数据样式:


import numpy as np
# listdir()列出给定目录的文件名
from os import listdir
import operator

# inX-分类的输入向量,dataSet-输入的训练样本集,labels-标签向量,k-近邻数
def classify0(inX,dataSet,labels,k):
    dataSetSize = dataSet.shape[0] # 得到训练集的行数,即样本个数
    # 以下三行距离计算计算
    # print("样本个数:",dataSetSize)
    diffMat = np.tile(inX,(dataSetSize,1)) - dataSet  # tile():拉伸copy
    # 将输入的测试样本沿行方向扩充为(4,2),减去训练样本的坐标,得到各自的距离
    # print("变形:",diffMat)
    sqDiffMat = diffMat ** 2  # 欧式距离平方
    sqDistances = sqDiffMat.sum(axis=1) # 欧式距离求和
    distances = sqDistances ** 0.5 # 开方
    sortedDistIndicies = distances.argsort() # 按distances中的数值大小依次返回索引给y
    # print("索引顺序:",sortedDistIndicies)
    classCount = {}
    # 以下两行选择距离最小的k个点
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
        # 0:{labels[2]="B","B":1} 1:("B":2) 2:("A":1)
        #get():返回指定键的值,如果值不在字典中返回默认值(此处设为0)
    # 排序
    # print("classCount.items():",classCount.items())
    sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    # operator.itemgetter(x):定义函数,获取对象的第x个域的值
    # key为函数,指定取待排序元素的哪一项进行排序
    # reverse = True 从大到小排序
    # print("sortedClassCount:",sortedClassCount)
    return sortedClassCount[0][0]

# 将图像转换为向量
def img2vector(filename):
    returnVect = np.zeros(1024)
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVect[32*i+j] = int(lineStr[j]) # 把逐行读取到的单行的每一项依次赋给
    return returnVect

def handwriteClassTest():
    hwLabels = []
    trainingFileList = listdir("./MLiA_SourceCode/machinelearninginaction/Ch02/digits/trainingDigits")
    m = len(trainingFileList) # 文件个数
    trainingMat = np.zeros((m,1024)) # m个样本,每个样本1024个数据
    for i in range(m):
        # 以下三行从文件名解析分类数字
        fileNameStr = trainingFileList[i] # 获取文件名
        fileStr = fileNameStr.split('.')[0]  # 文件名去后缀
        classNumStr = int(fileStr.split('_')[0]) # 获取文件数据所表示的值
        hwLabels.append(classNumStr)
        # 用样本值替换全0数组
        trainingMat[i, :] = img2vector('./MLiA_SourceCode/machinelearninginaction/Ch02/digits/trainingDigits/%s'\
                                       %fileNameStr)
    testFileList = listdir('./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('./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.0
        print("\nthe total number of errors is: %d"%errorCount)
    print("\nthe total error rate is: %f" % (errorCount / float(mTest)))

if __name__ == "__main__":
    handwriteClassTest()

"""
实际使用这个算法时,算法的执行效率并不高。因为算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,
总计要执行900次,此外,我们还需要为测试向量准备2MB的存储空间。

k决策树就是k近邻算法的优化版,可以节省大量的计算开销。
"""


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值