使用先前的分类算法classify0对手写数字进行识别
1.准备数据,将图像转换为测试向量
def img2vector(filename):
returnVect=np.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
2.手写数字识别系统测试
def handwritingClassTest():
hwLabels=[]
trainingFileList=os.listdir('训练数据文件夹路径')#listdir返回文件夹下所有文件名
m=len(trainingFileList)#得到训练数据个数
trainingMat=np.zeros((m,1024))
for i in range(m):
fileNameStr=trainingFileList[i]#依次取出文件名,即训练数据名
fileStr=fileNameStr.split('.')[0]#0_1.txt这个文件名按 "."分割,取格式名前面的部分
classNumStr=int(fileStr.split('_')[0])#0_1按_分割,取前面一个数字
hwLabels.append(classNumStr)
trainingMat[i,:]=img2vector('训练数据文件夹路径\%s' %fileNameStr)
testFileList=os.listdir('测试数据文件夹路径')
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('测试数据文件夹路径\%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
print "\nthe total number of errors is:%d" %errorCount
print "\nthe total error rate is:%f"%(errorCount/float(mTest))
handwritingClassTest()
总结:
实际使用这个算法时,算法的执行效率并不高。因为算法需要为每个测试向量做2000次距离计算,每个距离计算包括了1024个维度浮点运算,总计要执行900次
此外,我们还需要为测试向量准备2 M B的存储空间。是否存在一种算法减少存储空间和计算时间的开销呢? 决策树就是k-近邻算法的优化版,可以节省大量的计算开销。
k-近邻算法是分类数据最简单有效的算法。k-近邻算法必须保存全部数据集,如果训练数据集很大,必须使用大量的存储空间。此外由于必须对数据集中的每个数据计算距离值,实际使用时可能非常耗时。
k-近邻算法的另一个缺陷是它无法给出任何数据的基础结构信息,因此我们也无法知晓平均实例样本和典型实例样本具有什么特征