手寫數字識別

4、 任務分析

  sklearn.neighbors模塊實現了k-近鄰算法。如圖1所示。python

 

圖1 sklearn.neighbors模塊

  KNeighborsClassifier函數有8個參數。如圖2所示。git

圖2 參數

  n_neighbors: int,可選,默認值爲5,最近的k個點算法

  weights: 權重,默認是uniformvim

  algorithm: 快速k近鄰搜索算法,默認參數爲autoapp

  leaf_size: int,可選,默認值爲30,構造kd樹和ball樹的大小函數

  p: 整數,可選,默認值爲2,距離度量公式測試

  metric: 用於距離度量spa

  metric_params: 距離公式的其餘關鍵參數操作系統

  n_jobs: 並行處理設置code

 ♥ 知識連接
sklearn
sklearn實現KNN的方法是sklearn.neighbors.KNeighborsClassifier。

5、 任務實施

步驟一、環境準備

  右擊Ubuntu操做系統桌面,從彈出菜單中選擇【Open in Terminal】命令 打開終端。

  經過【cd /home】切換到home目錄下。【ls】查看該目錄下的全部內容。如圖3所示。

圖3 切換目錄

  【mkdir KNN】在home目錄下建立KNN文件夾。如圖4所示。

圖4 建立文件夾

步驟二、數據集

  【cd KNN】切換至KNN目錄下,【cp -R /home/soft/digits/ /home/KNN/】將數據從/home/soft目錄下拷貝至/home/KNN目錄下,【cd digits】切換至數據目錄下查看,該目錄下分別放置訓練數據集和測試數據集的文件夾。如圖5所示。

圖5 拷貝數據集

  【cd testDigits】切換至測試數據集的文件夾中查看,全部的文本格式存儲的數字文件命名格式爲:數字的值_該數字的樣本序號。訓練數據集和測試數據集是同樣的格式。可自行查看。如圖6所示。

圖6 文本格式

  每個文本中都包含32像素x32像素的數字。可經過【cat】命令查看任意文件。如圖7所示。

圖7 文本內容

步驟三、K-近鄰算法

  【cd ../..】切換至KNN目錄下,【vim kNN_digits.py】回車後建立並編輯名爲kNN_digits的Python文件。如圖8所示。

圖8 建立Python文件

  回車後進入編輯框內,按鍵盤【i】進入編輯狀態,編譯以下程序。如圖9所示。

  【import numpy as np】導入numpy矩陣庫

  【import operator】導入運算符模塊

  【from os import listdir】導入os模塊,操做文件夾

  【from sklearn.neighbors import KNeighborsClassifier as kNN】導入sklearn庫

圖9 模塊

  將32x32的二進制圖像轉換爲1x1024向量。如圖10所示。

圖10 向量轉換

  建立手寫數字分類測試函數hangwritingClassTest,分別獲得訓練集訓練的矩陣及類別,經過sklear的KNN近鄰算法訓練模型。如圖11所示。

圖11 訓練模型

  在hangwritingClassTest內繼續獲得測試數據集的矩陣,經過neigh.predict對測試數據進行預測。最後經過出現的錯誤數除以總的個數獲得錯誤率。如圖12所示。

圖12 預測

  在main函數內調用hangwritingClassTest函數。如圖13所示。

圖13 main方法

  編輯完畢後,按【esc】退出編輯狀態,【:wq】保存並退出編輯框,【python kNN_digits.py】執行kNN_digits的Python文件,結果以實際預測爲準。如圖14所示。

 

圖14 運行Python文件

步驟四、源碼

 1 #coding:utf-8
 2 import numpy as np
 3 import operator
 4 from os import listdir
 5 from sklearn.neighbors import KNeighborsClassifier as kNN
 6 """
 7 將32x32的二進制圖像轉換爲1x1024向量
 8 """
 9 def img2vector(filename):
10     returnVect = np.zeros((1,1024)) #生成1x1024零向量
11     fr = open(filename) #打開文件
12     for i in range(32): #文本格式是32x32的,讀取全部行
13         lineStr = fr.readline() #讀一行數據
14         for j in range(32): #讀取行中全部元素
15             returnVect[0, 32*i+j] = int(lineStr[j]) #將全部的元素添加到returnVect中
16     return returnVect #返回轉換後的1x1024向量
17 """
18 手寫數字分類測試
19 """
20 def handwritingClassTest():
21     hwLabels = [] #訓練集的Labels
22     trainingFileList = listdir('digits/trainingDigits') #返回trainingDigits目錄下的文件名
23     m = len(trainingFileList) #返回文件夾下文件的個數
24     trainingMat = np.zeros(((m,1024))) #初始化訓練的矩陣
25     for i in range(m): 
26         fileNameStr = trainingFileList[i] #得到文件的名字
27         classNumber = int(fileNameStr.split('_')[0]) #得到分類的數字
28         hwLabels.append(classNumber) #將得到的類別添加到hwLabels中
29         #將每個文件的1x1024數據存儲到trainingMat矩陣中
30         trainingMat[i,:] = img2vector("digits/trainingDigits/%s" % (fileNameStr))
31     neigh = kNN(n_neighbors=3,algorithm="auto") #構建kNN分類器
32     neigh.fit(trainingMat,hwLabels) #訓練模型
33     testFileList = listdir("digits/testDigits") #返回TestDigits目錄下的文件列表
34     errorCount = 0.0 #錯誤檢測計數
35     mTest = len(testFileList) #測試數據的數量
36     for i in range(mTest): #從文件中解析出測試集的類別並進行分類測試
37         fileNameStr = testFileList[i] #得到文件名字
38         classNumber = int(fileNameStr.split("_")[0]) #得到分類的數字
39         vectorUnderTest = img2vector("digits/testDigits/%s" % (fileNameStr)) #得到測試集的1x1024向量,用於訓練
40         classifierResult = neigh.predict(vectorUnderTest) #獲取預測結果
41         print "分類返回結果爲%d\t真實結果爲%d" % (classifierResult,classNumber)
42         if (classifierResult != classNumber):
43             errorCount += 1.0
44     print "總共錯了%d個數據\n錯誤率爲%f%%" % (errorCount,errorCount/mTest * 100)
45 if __name__ == '__main__':
46     handwritingClassTest()
相關文章
相關標籤/搜索