日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

基于kNN的手写字体识别——《机器学习实战》笔记

發(fā)布時間:2023/12/18 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于kNN的手写字体识别——《机器学习实战》笔记 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

看完一節(jié)《機(jī)器學(xué)習(xí)實戰(zhàn)》,算是踏入ML的大門了吧!這里就詳細(xì)講一下一個demo:使用kNN算法實現(xiàn)手寫字體的簡單識別

kNN

 先簡單介紹一下kNN,就是所謂的K-近鄰算法:

  【作用原理】:存在一個樣本數(shù)據(jù)集合、每個樣本數(shù)據(jù)都存在標(biāo)簽。輸入沒有標(biāo)簽的新數(shù)據(jù)后,將新數(shù)據(jù)的每個特征與樣本集數(shù)據(jù)的對應(yīng)特征進(jìn)行比較,然后算法提取樣本集中最相似的分類標(biāo)簽。一般說來,我們只選擇樣本數(shù)據(jù)集中前k個最相似的數(shù)據(jù),最后,選擇這k個相似數(shù)據(jù)中出現(xiàn)次數(shù)最多的分類,作為新數(shù)據(jù)的分類。

  通俗的說,舉例說明:有一群明確國籍的人(樣本集合,比如1000個):中國人、韓國人、日本人、美國人、埃及人,現(xiàn)在有一個不知國籍的人,想要通過比較特征來猜測他的國籍(當(dāng)然,特征具有可比較性和有效性),通過比較特征,得出特征與該人最相近的樣本集中的9個人(k),其中,1個是韓國人、2個是日本人,6個是中國人,那么這個人是中國人的可能性就很大。

  這就是kNN的基本思想。

手寫體識別數(shù)據(jù)準(zhǔn)備

  kNN輸入需要特征矩陣,一般是固定大小的二值圖像,這里我們使用書上提供的數(shù)據(jù)集:這個數(shù)據(jù)集使用32X32文本文件存儲數(shù)值圖像。例如下圖的'9'

?

  這里每個文本文件存儲一個手寫體數(shù)據(jù),并且文件名寫成"number_num.txt"這樣的形式,例如9_1.txt,方便后期提取標(biāo)簽

  我們將樣本數(shù)據(jù)放在trainingDigits文件夾中,測試樣例存儲在testDigits文件夾中

  我們在處理時將每個手寫體數(shù)據(jù)(32x32)轉(zhuǎn)換成1X1024維的向量。

  另外,kNN涉及到相似度計算。這里我們使用的是歐氏距離,由于手寫體數(shù)據(jù)向量是規(guī)則的二值數(shù)據(jù),因此不需要進(jìn)行歸一化。

手寫體識別算法運(yùn)行流程

  (一)讀取手寫體txt文件,轉(zhuǎn)化為1X1024向量

    我們創(chuàng)建一個kNN.py,添加模塊img2vector

1 #識別手寫字體模塊-圖像轉(zhuǎn)向量32x32 to 1x1024 2 def img2vector(filename): 3 returnVect = zeros((1,1024)) 4 fr = open(filename) 5 for i in range(32): 6 lineStr = fr.readline() 7 for j in range(32): 8 returnVect[0,32*i+j] = int(lineStr[j]) 9 return returnVect

    我們的樣本數(shù)據(jù)和測試數(shù)據(jù)都需要用到該函數(shù)

  (二)比較測試數(shù)據(jù)和樣本數(shù)據(jù)集的距離,返回k近鄰中最相似的標(biāo)簽

    在kNN.py中添加classify0模塊,附上代碼注釋  

1 #--------------------------------------------- 2 #分類模塊 3 #@params 4 # inX:輸入向量、手寫體識別的測試向量 5 # dataSet:訓(xùn)練集樣本、手寫體識別的訓(xùn)練集向量 6 # labels:訓(xùn)練集對應(yīng)的標(biāo)簽向量 7 # k:最近鄰居數(shù)目、本實驗為3 8 #--------------------------------------------- 9 def classifiy0(inX, dataSet, labels, k): 10 dataSetSize = dataSet.shape[0] #手寫體樣本集容量 11 #(以下三行)距離計算 12 diffMat = tile(inX, (dataSetSize,1)) - dataSet 13 sqDiffMat = diffMat**2 14 sqDistances = sqDiffMat.sum(axis=1) 15 distances = sqDistances**0.5 #歐氏距離開平方 16 sortedDistIndicies = distances.argsort() #距離排序的索引排序 17 classCount = {} 18 #(以下兩行)選擇距離最小的k個點 19 for i in range(k): 20 voteIlabel = labels[sortedDistIndicies[i]] 21 classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1 22 sortedClassCount = sorted(classCount.items(), 23 #排序 24 key = operator.itemgetter(1), reverse = True) 25 return sortedClassCount[0][0]

    注意,這里使用了numpy的接口,在kNN.py的開頭要加上:from numpy import* 

  (三)比較標(biāo)簽與測試結(jié)果,計算正確率

    同樣,在kNN.py中添加handwritingClassTest模塊,綜合以上的兩個模塊,獲得識別正確率

1 #手寫識別的測試代碼 2 def handwritingClassTest(): 3 hwLabels = [] 4 trainingFileList = listdir(path='trainingDigits') #獲取目錄內(nèi)容 5 m = len(trainingFileList) 6 trainingMat = zeros((m,1024)) 7 for i in range(m): 8 #一下三行,從文件名解析分類數(shù)字 9 fileNameStr = trainingFileList[i] 10 fileStr = fileNameStr.split('.')[0] 11 classNumStr = int(fileStr.split('_')[0]) 12 13 hwLabels.append(classNumStr) 14 trainingMat[i,:] = img2vector('trainingDigits/%s'%fileNameStr) 15 testFileList = listdir(path='testDigits') 16 17 errorCount = 0.0 #錯誤個數(shù)計數(shù)器 18 mTest = len(testFileList) 19 20 #從測試數(shù)據(jù)中提取數(shù)據(jù) 21 for i in range(mTest): 22 fileNameStr = testFileList[i] 23 fileStr = fileNameStr.split('.')[0] 24 25 classNumStr = int(fileStr.split('_')[0]) 26 vectorUnderTest = img2vector('testDigits/%s'% fileNameStr) 27 classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3) 28 29 print("the classifier came back with:%d,the real answer is:%d"%(classifierResult,classNumStr)) 30 if(classifierResult != classNumStr): 31 errorCount += 1.0 32   #輸出結(jié)果 33 print("\nthe total number of errors is:%d"%errorCount) 34 print("\nthe total error rate is: %f"%(errorCount/float(mTest)))

    注意,這里使用到了os模塊listdir,在kNN開頭加入:from numpy import listdir

  測試結(jié)果如下:

  錯誤率為1.16%,可以看到,識別效果挺不錯。

后記

  通過實驗我們可以看到,使用kNN要將訓(xùn)練樣本一次性加載入內(nèi)存、如果訓(xùn)練集的規(guī)模很大,勢必對機(jī)器有很大的要求。另外,kNN不需要訓(xùn)練算法、對異常值不敏感、在后期使用的時候要慎重選擇吧

?

?

    

?

 

轉(zhuǎn)載于:https://www.cnblogs.com/HolyShine/p/6358554.html

總結(jié)

以上是生活随笔為你收集整理的基于kNN的手写字体识别——《机器学习实战》笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。