【机器学习实战】k近邻算法实战——手写识别系统
文章目录
- 手写识别系统
- 步骤:
- 准备数据:将图像转换为测试向量
- 测试算法:使用k-近邻算法识别手写数字
- 【完整代码】
手写识别系统
为了简单起见,这里构造的系统只能识别数字0到9,参见图2-6。需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小[插图]:宽高是32像素×32像素的黑白图像。尽管采用文本格式存储图像不能有效地利用内存空间,但是为了方便理解,我们还是将图像转换为文本格式。
步骤:
- 收集数据:提供文本文件。
- 准备数据:编写函数img2vector(),将图像格式转换为分类器使用的向量格式。
- 分析数据:在Python命令提示符中检查数据,确保它符合要求。
- 训练算法:此步骤不适用于k-近邻算法。
- 测试算法:编写函数使用提供的部分数据集作为测试样本,测试样本与非测试样本的区别在于测试样本是已经完成分类的数据,如果预测分类与实际类别不同,则标记为一个错误。
- 使用算法:本例没有完成此步骤,若你感兴趣可以构建完整的应用程序,从图像中提取数字,并完成数字识别,美国的邮件分拣系统就是一个实际运行的类似系统。
准备数据:将图像转换为测试向量
实际图像存储在第2章源代码的两个子目录内:目录trainingDigits中包含了大约2000个例子,每个例子的内容如图2-6所示,每个数字大约有200个样本;目录testDigits中包含了大约900个测试数据。我们使用目录trainingDigits中的数据训练分类器,使用目录testDigits中的数据测试分类器的效果。两组数据没有重叠,你可以检查一下这些文件夹的文件是否符合要求。(【下载地址】
为了使用前面两个例子的分类器,我们必须将图像格式化处理为一个向量。我们将把一个32× 32的二进制图像矩阵转换为1×1024的向量,这样前两节使用的分类器就可以处理数字图像信息了。
我们首先编写一段函数img2vector,将图像转换为向量:该函数创建1×1024的NumPy数组,然后打开给定的文件,循环读出文件的前32行,并将每行的头32个字符值存储在NumPy数组中,最后返回数组。
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
进行测试:
testVector = img2vector('digits/testDigits/0_13.txt')
print(testVector[0, 0:31])
print(testVector[0, 32:63])
================================
[0. 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. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0.0. 0. 0. 0. 0. 0. 0.]
测试算法:使用k-近邻算法识别手写数字
函数handwritingClassTest()是测试分类器的代码,将其写入kNN.py文件中。在写入这些代码之前,我们必须确保将from os import listdir写入文件的起始部分,这段代码的主要功能是从os模块中导入函数listdir,它可以列出给定目录的文件名。
# 测试分类器
def handwritingClassTest():hwLabels = []# 获取目录内容trainingFileList = listdir('digits/trainingDigits')m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):# 从文件名解析分类数字fileNameStr = trainingFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])hwLabels.append(classNumStr)trainingMat[i, :] = img2vector('digits/trainingDigits/%s' % fileNameStr)testFileList = listdir('digits/testDigits')errorCount = 0.0mTest = len(testFileList)for i in range(mTest):fileNameStr = testFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])vectorUnderTest = img2vector('digits/testDigits/%s' % fileNameStr)classfierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)print("the classifier came back with %d, the real answer is %d" % (classfierResult, classNumStr))if (classfierResult != classNumStr): errorCount += 1.0print("\n the total number of errors is : %d" % errorCount)print("\n the total error rate is : %f" % (errorCount / float(mTest)))
将trainingDigits目录中的文件内容存储在列表中1,然后可以得到目录中有多少文件,并将其存储在变量m中。接着,代码创建一个m行1024列的训练矩阵,该矩阵的每行数据存储一个图像。我们可以从文件名中解析出分类数字2。该目录下的文件按照规则命名,如文件9_45.txt的分类是9,它是数字9的第45个实例。然后我们可以将类代码存储在hwLabels向量中,使用前面讨论的img2vector函数载入图像。在下一步中,我们对testDigits目录中的文件执行相似的操作,不同之处是我们并不将这个目录下的文件载入矩阵中,而是使用classify0()函数测试该目录下的每个文件。由于文件中的值已经在0和1之间,本节并不需要使用2.2节的autoNorm()函数。
测试:
handwritingClassTest()
=====================================
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
the classifier came back with 0, the real answer is 0
......
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9
the classifier came back with 9, the real answer is 9the total number of errors is : 10the total error rate is : 0.010571
k-近邻算法识别手写数字数据集,错误率为1.1%。改变变量k的值、修改函数handwriting-ClassTest随机选取训练样本、改变训练样本的数目,都会对k-近邻算法的错误率产生影响,感兴趣的话可以改变这些变量值,观察错误率的变化。
实际使用这个算法时,算法的执行效率并不高。因为算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,总计要执行900次,此外,我们还需要为测试向量准备2MB的存储空间。是否存在一种算法减少存储空间和计算时间的开销呢?k决策树就是k-近邻算法的优化版,可以节省大量的计算开销。
【完整代码】
from numpy import *
import operatordef classify0(inX, dataSet, labels, k):dataSetSize = dataSet.shape[0]# 距离计算diffMat = tile(inX, (dataSetSize, 1)) - dataSetsqDiffMat = diffMat ** 2sqDistances = sqDiffMat.sum(axis=1)distances = sqDistances ** 0.5sortedDistIndicies = distances.argsort()classCount = {}# 选择距离最小的k个点for i in range(k):voteIlabel = labels[sortedDistIndicies[i]]classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1# 排序sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1), reverse=True)return sortedClassCount[0][0]def autoNorm(dataSet):minVals = dataSet.min(0)maxVals = dataSet.max(0)ranges = maxVals - minValsnormDataSet = zeros(shape(dataSet))m = dataSet.shape[0]normDataSet = dataSet - tile(minVals, (m, 1))# 特征值相除normDataSet = normDataSet / tile(ranges, (m, 1))return normDataSet, ranges, minVals# 手写识别####################### 将图像转换为向量
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#
# testVector = img2vector('digits/testDigits/0_13.txt')
# print(testVector[0, 0:31])
# print(testVector[0, 32:63])from os import listdir# 测试分类器
def handwritingClassTest():hwLabels = []# 获取目录内容trainingFileList = listdir('digits/trainingDigits')m = len(trainingFileList)trainingMat = zeros((m, 1024))for i in range(m):# 从文件名解析分类数字fileNameStr = trainingFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])hwLabels.append(classNumStr)trainingMat[i, :] = img2vector('digits/trainingDigits/%s' % fileNameStr)testFileList = listdir('digits/testDigits')errorCount = 0.0mTest = len(testFileList)for i in range(mTest):fileNameStr = testFileList[i]fileStr = fileNameStr.split('.')[0]classNumStr = int(fileStr.split('_')[0])vectorUnderTest = img2vector('digits/testDigits/%s' % fileNameStr)classfierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)print("the classifier came back with %d, the real answer is %d" % (classfierResult, classNumStr))if (classfierResult != classNumStr): errorCount += 1.0print("\n the total number of errors is : %d" % errorCount)print("\n the total error rate is : %f" % (errorCount / float(mTest)))handwritingClassTest()
【机器学习实战】k近邻算法实战——手写识别系统相关推荐
- 【Python】基于kNN算法的手写识别系统的实现与分类器测试
基于kNN算法的手写识别系统 1. 数据准备 使用windows画图工具,手写0-9共10个数字,每个数字写20遍,共200个BMP文件. 方法如下,使用画图工具,打开网格线,调整像素为32 ...
- knn算法测试手写识别系统准确率
手写识别系统,KNN算法实现手写识别系统的准确率 (准确率=测试分对的样本数/总的样本数) import numpy as np from itertools import chain from os ...
- Knn算法之手写识别系统
knn值之手写识别系统 导入包 import numpy as np from os import listdir import operator 介绍 1.os模块 os.listdir() 方法用 ...
- k近邻算法_图穷匕见:K近邻算法与手写数字识别
机器学习算法是从数据中产生模型,也就是进行学习的算法.我们把经验提供给算法,它就能够根据经验数据产生模型.在面对新的情况时,模型就会为我们提供判断(预测)结果.例如,我们根据"个子高.腿长. ...
- 机器学习实战——2.3 示例:手写识别系统
目录 1.准备数据:将图像转换为测试向量 2.测试算法:使用K-近邻算法识别手写数字 1.准备数据:将图像转换为测试向量 为了使用之前编辑好的classify0()分类器,我们必须将图像格式化处理为一 ...
- 机器学习实战-手写识别系统
在实现了K近邻算法后,书中给出了一个实例,今天来学习一下使用K近邻分类器的手写识别系统.书中原带的文件已经过处理转换为了文本格式,方便了许多. 先看一下原带文件 准备数据 #将图像转换为测试向量 de ...
- java手写识别_手写识别系统
目的 采用k-近邻算法实现手写识别系统.这里采用0和1组成数字0-9的形状,再用算法对这些形状进行识别,来分辨出形状属于0-9那个数字.并计算出k-近邻算法识别手写数字的错误率. 数据说明 数据来自& ...
- 机器学习之k近邻算法
本文的代码基于书本<机器学习实战> 概念 k-近邻算法采用测量不同特征值之间距离的方法进行分类.工作原理是:存在一个样本数据集合,称作训练样本集,样本中每个数据都存在标签.输入没有标签的新 ...
- 机器学习算法(一):k-近邻理论与python实现+经典应用(约会网站匹配、手写识别系统)
一份算法学习笔记~ 亲爱的朋友,恭喜你点开神秘之门,哈哈哈哈!从这里开始,我们一起学习机器学习的经典算法吧. 这一次的主要内容是机器学习入门算法:k-近邻.理论相当好理解,下面我们正式开始啦! 算法简 ...
最新文章
- - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
- 【剑指offer - C++/Java】8、跳台阶
- 【软件】OBS无法捕捉显示屏
- 包装类 与 简单集合框架
- sapi cli php mac,make: *** [sapi/cli/php] Error 1 解决办法
- django excel 导出页面_Django Admin中增加导出Excel功能过程解析
- SQL-92标准 中文翻译——定义、记号和约定 (记号)
- 你能在windows上创建一个叫做AUX的文件夹吗?
- Alfresco 4 项目介绍
- 安卓应用市场互相抓取app包
- 谈谈创业这点事 专业的盲区
- Stream流创建,常用方法
- python使用h5py读取mat文件数据
- PDF电子发票内容提取
- 这一篇说明大多数SQL优化的面试问题
- 哥尼斯堡的“七桥问题” (25分)
- 20210209PC版微信 网络不可用,请检查你的网络设置 的解决方法
- 如何用计算机名查看共享打印机,共享打印机怎么连接?打印机如何共享?查看图文帮你解决...
- iOS开发-技术知识盘点总结(二)
- 【IT软件专利】---专利编写步骤