机器学习 & python k-近邻算法处理手写识别系统

本文介绍了一个基于k-近邻算法的手写数字识别系统实现过程。系统通过将图像转换为向量,利用训练集进行分类器训练,并在测试集上评估准确率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

参考自:《Machine Learning In Action》第二章


##########################################################


识别数字0-9。需要识别的数字已经使用图形处理软件,处理成具有相同的色彩和大小:宽高是32x32像素的黑白图像


程序所需文件:http://download.youkuaiyun.com/detail/u012005313/9191581


程序代码:

#!/usr/local/env python
#-*- coding: utf-8 -*-

from numpy import * #导入科学计算包numpy模块
import operator  #导入运算符模块
from os import listdir #导入os模块

#k-近邻分类算法
def classify0(inX, dataSet, labels, k): #4个输入参数分别为:用于分类的输入向量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  #计算欧式距离
	#选择距离最小的k个点 计算所属类别的出现频率
	sortedDistIndicies=distances.argsort() #取得输入向量和数据集中各向量欧式距离的从小到大排序的下标值
	classCount={}  #定义一个空字典
	for i in range(k):  #取计算欧氏距离排序后最小的前k个值
		voteIlabel=labels[sortedDistIndicies[i]]
		classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
	#排序 选择前k个点中出现最多的那一个类
	sortedClassCount=sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
	return sortedClassCount[0][0]

#将图像转换为向量
def img2vector(filename): #输入参数为文件名字符串
	returnVect=zeros((1,1024)) #初始化1x1024大小的向量
	fr=open(filename) #打开文件
	for i in range(32): #循环读取文件的前32行
		lineStr=fr.readline() #返回文件的一行数据
		for j in range(32): #读取每行的前32个字符值
			returnVect[0, 32*i+j]=int(lineStr[j])
	return returnVect #返回数组
	
#手写数字识别系统的测试代码
def handwritingClassTest():
	hwLabels=[]
	trainingFileList=listdir('digits/trainingDigits') #以列表形式返回path路径下的所有文件名
	m=len(trainingFileList) #文件的数量	
	trainingMat=zeros((m, 1024))	
	for i in range(m): 
		#从文件名解析分类数字
		fileNameStr=trainingFileList[i]
		fileStr=fileNameStr.split('.')[0] #例:0_0.txt
		classNumStr=int(fileStr.split('_')[0])
		hwLabels.append(classNumStr)
		trainingMat[i,:]=img2vector('digits/trainingDigits/%s'%fileNameStr)
	testFileList=listdir('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('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))

实际图像存储在digits目录下的两个子目录内:目录trainingDigits中包含了大约2000个例子,每个数字大约有200个样本;目录testDigits中包含了大约900个测试数据。

使用目录trainingDigits中的数据训练分类器,使用目录testDigits中的数据测试分类器的效果


首先编写函数img2vector,将图像转换为向量:该函数创建1x1024的Numpy数组,然后打开给定文件,循环读取文件的前32行,并将每行的头32个字符值存储在Numpy数组中,最后返回数组


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值