使用先前的分類算法classify0對手寫數(shù)字進(jìn)行識(shí)別
1.準(zhǔn)備數(shù)據(jù)嗅钻,將圖像轉(zhuǎn)換為測試向量
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.手寫數(shù)字識(shí)別系統(tǒng)測試
def handwritingClassTest():
hwLabels=[]
trainingFileList=os.listdir('訓(xùn)練數(shù)據(jù)文件夾路徑')#listdir返回文件夾下所有文件名
m=len(trainingFileList)#得到訓(xùn)練數(shù)據(jù)個(gè)數(shù)
trainingMat=np.zeros((m,1024))
for i in range(m):
fileNameStr=trainingFileList[i]#依次取出文件名,即訓(xùn)練數(shù)據(jù)名
fileStr=fileNameStr.split('.')[0]#0_1.txt這個(gè)文件名按 "."分割,取格式名前面的部分
classNumStr=int(fileStr.split('_')[0])#0_1按_分割,取前面一個(gè)數(shù)字
hwLabels.append(classNumStr)
trainingMat[i,:]=img2vector('訓(xùn)練數(shù)據(jù)文件夾路徑\%s' %fileNameStr)
testFileList=os.listdir('測試數(shù)據(jù)文件夾路徑')
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('測試數(shù)據(jù)文件夾路徑\%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()
總結(jié):
實(shí)際使用這個(gè)算法時(shí),算法的執(zhí)行效率并不高铅乡。因?yàn)樗惴ㄐ枰獮槊總€(gè)測試向量做2000次距離計(jì)算,每個(gè)距離計(jì)算包括了1024個(gè)維度浮點(diǎn)運(yùn)算烈菌,總計(jì)要執(zhí)行900次
此外阵幸,我們還需要為測試向量準(zhǔn)備2 M B的存儲(chǔ)空間。是否存在一種算法減少存儲(chǔ)空間和計(jì)算時(shí)間的開銷呢芽世? 決策樹就是k-近鄰算法的優(yōu)化版挚赊,可以節(jié)省大量的計(jì)算開銷。
k-近鄰算法是分類數(shù)據(jù)最簡單有效的算法济瓢。k-近鄰算法必須保存全部數(shù)據(jù)集荠割,如果訓(xùn)練數(shù)據(jù)集很大,必須使用大量的存儲(chǔ)空間旺矾。此外由于必須對數(shù)據(jù)集中的每個(gè)數(shù)據(jù)計(jì)算距離值蔑鹦,實(shí)際使用時(shí)可能非常耗時(shí)。
k-近鄰算法的另一個(gè)缺陷是它無法給出任何數(shù)據(jù)的基礎(chǔ)結(jié)構(gòu)信息箕宙,因此我們也無法知曉平均實(shí)例樣本和典型實(shí)例樣本具有什么特征