【Python】基于kNN算法的手写识别系统的实现与分类器测试
基于kNN算法的手写识别系统
1. 数据准备
使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件。
方法如下,使用画图工具,打开网格线,调整像素为32*32,如下图所示
将文件保存为单色BMP文件
2. 将图片文件转换为一维向量
1) 以二进制方式打开BMP文件3_0.txt
2) 根据BMP文件编码规则可知,单色位图BMP文件从第63-190位共128位是BMP位图数据部分。截取数据部分。
3) 将其转化为8位2进制文件,然后写入3_0.txt,并注意到每32个字节需要加入一个换行符
4) 调试中发现,上述文件是倒着的,因为BMP二进制数据存储顺序,从左到右,从下到上,重新将文件读入内存,然后按行倒序写入TXT文件
Python代码如下:
至此,批量实现BMP转换为同名TXT文件
3. kNN算法代码
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies = distances.argsort()
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,1) + 1
sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1), reverse=True)
returnsortedClassCount[0][0]
4. 欧氏距离算法代码
dataSetSize= dataSet.shape[0]
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1)
distances = sqDistances**0.5
sortedDistIndicies= distances.argsort()
5. 马氏距离代码算法
defclassify1(inX,dataSet,n,labels, k):
testFileList= listdir('testDigits') #iteratethrough the test set
mTest = len(testFileList)
distances=zeros((10,10))
for i in range(mTest):
diffMat = inX - dataSet[i]
diffMatT=(diffMat.T)
sqDiffMat = dot(diffMat,diffMat.T)
distances[n][i] = sqrt(sqDiffMat)
distanczzesArg=distances[n].argsort()
sortedDistIndicies=distanczzesArg
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,1) + 1
sortedClassCount = sorted(classCount.iteritems(),key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
6. 测试分类器,分析识别错误率
a) 欧氏距离
defhandwritingClassTest():
hwLabels = []
trainingFileList =listdir('trainingDigits') #loadthe training set
m = len(trainingFileList)
trainingMat = zeros((m,1024))
for i in range(m):
fileNameStr = trainingFileList[i] #0_0.txt
fileStr = fileNameStr.split('.')[0] #take off .txt 0_0
classNumStr =int(fileStr.split('_')[0])#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 backwith: %d, the real answer is: %d" % (classifierResult, classNumStr)
if (classifierResult != classNumStr):errorCount += 1.0
print "\nthe total number of errorsis: %d" % errorCount
print "\nthe total error rate is:%f" % (errorCount/float(mTest))
基于kNN手写识别算法测试结果
the classifiercame back with: 0, the real answer is: 0
the classifiercame back with: 1, the real answer is: 1
the classifiercame back with: 0, the real answer is: 2
the classifiercame back with: 0, the real answer is: 3
the classifiercame back with: 4, the real answer is: 4
the classifiercame back with: 5, the real answer is: 5
the classifiercame back with: 0, the real answer is: 6
the classifiercame back with: 7, the real answer is: 7
the classifiercame back with: 8, the real answer is: 8
the classifiercame back with: 9, the real answer is: 9
the total numberof errors is: 3
the total errorrate is: 0.300000
7. 心得体会
1) 如何将BMP文件批量转换为32X32的TXT文件很关键,期间也遇到了如下问题,不断调试代码,最终成功生成
a) 提取BMP二进制数据,查阅BMP编码规则,对于黑白单色BMP文件从63字节起是BMP数据部分
b) 直接读取BMP文件,获取的是16进制字符串,需要循环使用ord()函数逐字节将16进制字符串转为起对应10进制数值,然后10进制转为2进制(注意许指定二进制位数为8位)
c) 写入TXT文件,默认没有换行,需要每4个16进制字节后插入一个”\n”,形成32行32列的2进制字符串
d) BMP二进制数据存储顺序,从左到右,从下到上存储。读取到32X32的TXT文件后,发现字符形状是倒置的,需要翻转TXT的行,将32行替换为第1行,第31行替换为第2行….
2) kNN算法,错误率比较高,当trainingDigits只有200个时,识别0-9数字,错误率可能达到30%
3) 手写笔迹如果太细,识别错误率较高
4) 准确理解欧式距离和马氏距离的含义是至关重要的,尤其是马氏距离,需要注意u代表是由同一类数字多次训练的算术平均值组成的(1,1024)数组
【Python】基于kNN算法的手写识别系统的实现与分类器测试相关推荐
- Knn算法之手写识别系统
knn值之手写识别系统 导入包 import numpy as np from os import listdir import operator 介绍 1.os模块 os.listdir() 方法用 ...
- 【机器学习实战】k近邻算法实战——手写识别系统
文章目录 手写识别系统 步骤: 准备数据:将图像转换为测试向量 测试算法:使用k-近邻算法识别手写数字 [完整代码] 手写识别系统 为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6.需要识 ...
- python实现基于KNN算法的手写数字识别系统 非常详细!!!!
一家懂得用细节留住客户的3年潮牌老店我必须支持!➕
- knn算法测试手写识别系统准确率
手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...
- 基于KNN算法的手写体数字识别
基于KNN算法的手写体数字识别 KNN分类算法是一种经典的分类算法,属于懒惰学习算法的一种. 1.算法原理 工作原理:存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道 ...
- java手写识别_手写识别系统
目的 采用k-近邻算法实现手写识别系统.这里采用0和1组成数字0-9的形状,再用算法对这些形状进行识别,来分辨出形状属于0-9那个数字.并计算出k-近邻算法识别手写数字的错误率. 数据说明 数据来自& ...
- 机器学习入门-kNN算法实现手写数字识别
实验环境 Python:3.7.0 Anconda:3-5.3.1 64位 操作系统:win10 开发工具:sublime text(非必要) 简介 本次实验中的重点为采用kNN算法进行手写数字识别, ...
- Python基于深度学习的手写数字识别
Python基于深度学习的手写数字识别 1.代码的功能和运行方法 2. 网络设计 3.训练方法 4.实验结果分析 5.结论 1.代码的功能和运行方法 代码可以实现任意数字0-9的识别,只需要将图片载入 ...
- kNN算法实现手写数字识别(机器学习)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.实验步骤 二.实验过程 1.收集数据:提供文本文件 2.准备数据:将图像转换为测试向量 3.测试算法:使用k-近邻 ...
最新文章
- Python Web 框架:Django MVC搭建
- 图像处理中的“内插”是什么?插值、图像内插值、图像间插值、重取样(用已知数据来估计未知位置的数值的处理)(最近邻内插法、双线性内插)
- java stream 求和_谈谈Java任务的并行处理
- DotNetOpenAuth实践之搭建验证服务器
- Android ListView的基本应用
- iOS 自定义layer的两种方式
- mysql数据库主从不同步_mysql数据库主从不同步的解决方法
- 项目方说性能达到百万TPS,如何测试它的可信度?
- WKWebView的customUserAgent
- java绘图-常用条形码类型组成及使用说明
- 逻辑删除还是物理删除
- spark学习之执行计划explain
- 给基于HEXO的博客添加gitter在线交流
- python塔防之------“红精灵来袭”
- cf----2019-10-28(Sad powers,Zebras,Not simply beatiful strings)
- Tiny4412 LCD驱动(DRM+设备树)
- MIPI 系列之 D-PHY
- iPhone手机 -- 如何找到开发者选项
- com.mysql.jdbc.exceptions.MySQLSyntaxErrorException
- 用U盘制作CentOS系统启动盘