栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

python实现手写识别系统

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python实现手写识别系统

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 前言
  • 一、手写识别系统
  • 二、主要步骤
    • 1.准备数据:将图像转换为测试向量
    • 2.测试算法:使用k-近邻算法识别手写数字
  • 总结



前言

    knn算法又称为k近邻分类(k-nearest neighbor classification)算法,核心思想:给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于这k个相邻点的信息进行预测。

    通常,在分类任务中可使用"投票法",即将这k个样本中出现最多的类别标记作为预测结果;在回归任务中可使用“平均法”,即将这k个样本的实际值输入标记的平均值作为预测结果;还可以基于距离远近进行加权平均或者加权投票,距离越近的样本权重越大。


一、手写识别系统

    本次构造的系统只能识别数字 0 到 9,参见于下面图像转化为测试向量中的例图‘0’。需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小 1:宽高是 32 像素 x 32 像素的黑白图像。通过分类器即KNN算法,当有一定的样本数据和这些数据所属的分类后,输入一个测试数据,就可以根据算法得出该测试数据属于哪个类别,此处的类别为 0-9 十个数字,就是十个类别。


二、主要步骤


1.准备数据:将图像转换为测试向量
def img2vector(filename):
    returnVect = zeros((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

为了使用分类器,我们必须将图像格式化处理为一个向量。我们将把一个 32x32 的二进制图像矩阵转换为 1x1024 的向量,这样前两节使用的分类器就可以处理数字图像信息了。首先编写一段函数 img2vector,将图像转换为向量:该函数创建 1x1024 的 NumPy 数组,然后打开给定的文件,循环读出文件的前 32 行,并将每行的头 32 个字符值存储在 NumPy 数组中,最后返回数组。下图为一个二进制图像矩阵‘0’的例子(将0~9,10个数据的手写体图片转化成文本存储(图片像素颜色,黑色用数字1替代,白色用0替代,图片像素大小为32*32))。 

 测试代码:

if __name__ == '__main__':
    testVector = img2vector('testDigits/0_13.txt')
    print(testVector[0, 0:31])

 输出结果:


2.测试算法:使用k-近邻算法识别手写数字
 
def handwritingClassTest():
    hwLabels = []
    trainingFileList = listdir('trainingDigits')           #load the training set
    m = len(trainingFileList)
    trainingMat = zeros((m,1024))
    for i in range(m):
        fileNameStr = trainingFileList[i]
        fileStr = fileNameStr.split('.')[0]     #take off .txt
        classNumStr = int(fileStr.split('_')[0])
        hwLabels.append(classNumStr)
        trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
    testFileList = listdir('testDigits')        #iterate through the test set
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]     #take off .txt
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest = img2vector('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)))

测试代码: 

    handwritingClassTest()

输出结果: 

 由此可见,错误率为1.1%。


总结

优点:精度高、对异常值不敏感、无数据输入假定。

缺点:时间复杂度高、空间复杂度高。

当样本不平衡时,比如一个类的样本容量很大,其他类的样本容量很小,输入一个样本的时候,K个临近值中大多数都是大样本容量的那个类,这时可能就会导致分类错误。改进方法是对K临近点进行加权,也就是距离近的点的权值大,距离远的点权值小。

计算量较大,每个待分类的样本都要计算它到全部点的距离,根据距离排序才能求得K个临近点,改进方法是:先对已知样本点进行剪辑,事先去除对分类作用不大的样本。

注:以上代码均来自《机器学习实战》 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/313744.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号