参考自:《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数组中,最后返回数组