机器学习实战--KNN算法实例之手写数字识别

1.示例描述:

系统识别的数字为0-9。数字图像为32*32的二进制图像,目录trainingDigits中大约2000个样本用于训练算法,目录testDigits中大约有900个样本用于测试。

数字图像以二进制的形式存储在记事本中。数字图像的形式如下所示,文件以数字的标签命名,下面这个数字图像的命名为“0_1.txt”,表示数字0的第1个样本。

2.KNN分类算法识别数字的步骤如下:

1.从trainingDigits文件中将所有的二进制图像进行解析,解析成数据集dataSet和对应样本的分类标签labels。

2.测试算法,并计算错误率。对testDigits中的文件进行解析,使用KNN算法判别每个二进制文件代表什么数字,并于测试样本的原有标签做对比,计算算法的错误率。

3.算法中涉及的函数如下:

1.image2vector(filename):对二进制图像进行解析。

2.classify(inX,dataSet,labels,k):对测试样本inX进行分类。

3.handWritingClassTest():测试算法,计算算法的错误率。

4.代码实现:

from numpy import *
import operator
from os import listdir                           #用于获取目录中的文件名
#将32*32的二进制图像矩阵转换为1*1024的向量
def image2vector(filename):
    returnVector=zeros((1,1024))
    with open(filename) as file:
        for i in range(32):
            line=file.readline()
            for j in range(32):
                returnVector[0,32*i+j]=int(line[j])
    return returnVector

#k-近邻算法
def classify(inX,dataSet,labels,k):
    num=dataSet.shape[0]                            #数据集中的样本个数
    diffMatrix=tile(inX,(num,1))-dataSet            #将测试向量转换为dataSet的同型矩阵并与dataSet做差
    #使用欧式距离公式求测试样本与训练集中样本的距离
    sqDiffMatrix=diffMatrix**2
    sqDistance=sqDiffMatrix.sum(axis=1)
    distance=sqDistance**0.5
    sortedDistIndicies=distance.argsort()            #对距离进行排序,返回排序后的索引值
    classCount={}
    for i in range(k):
        label=labels[sortedDistIndicies[i]]
        classCount[label]=classCount.get(label,0)+1  #若字典中存在label键,则对应的值+1,如果不存在,则添加这个键设置为0并+1
    sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) #按照字典中的值对字典进行降序排列
    return sortedClassCount[0][0]

#手写数字识别的测试代码
def handWritingClassTest():
    labels=[]
    trainingFileList=listdir('trainingDigits')     #获取训练集目录下的文件名
    m=len(trainingFileList)                        #计算训练样本个数
    dataSet=zeros((m,1024))                        #初始化数据集
    for i in range(m):
        fileName=trainingFileList[i]
        number=int(fileName.split('_')[0])         #number为每个样本的分类
        labels.append(number)
        dataSet[i,:]=image2vector('trainingDigits\%s'%fileName)
    testFileList=listdir('testDigits')
    mTest=len(testFileList)
    error=0.0
    for i in range(mTest):
        fileName=testFileList[i]
        number=int(fileName.split('_')[0])
        testVector=image2vector('testDigits\%s'%fileName)
        resultNumber=classify(testVector,dataSet,labels,3)      #使用算法估计样本所属类别
        if number!=resultNumber:                                #算法结果与样本的实际分类做对比
            error+=1.0
    print('the total number of errors is:',error)
    print('the total error rate is:',error/mTest)

handWritingClassTest()

运行结果:

the total number of errors is: 10.0
the total error rate is: 0.010570824524312896

 

5.KNN算法分析:

1.算法执行效率低:算法需要为每个测试向量做大约2000次距离计算,每个距离计算包括了1024个维度浮点计算,总共要执行900次。此外,还需要为测试向量准备一定的存储空间。所以这个算法不仅耗时,而且需要不少的存储空间。

2.k-临近算法的另一个缺陷就是它无法给出任何数据的基础结构信息,因此我们无法得知平均实例样本和典型实例样本具体有什么特征。

3.k-近邻算法是分类数据最简单最有效的算法。

 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值