sklearn.neighbors模塊實現了k-近鄰算法。如圖1所示。python
KNeighborsClassifier函數有8個參數。如圖2所示。git
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
♥ 知識連接 |
|
步驟一、環境準備
右擊Ubuntu操做系統桌面,從彈出菜單中選擇【Open in Terminal】命令 打開終端。
經過【cd /home】切換到home目錄下。【ls】查看該目錄下的全部內容。如圖3所示。
【mkdir KNN】在home目錄下建立KNN文件夾。如圖4所示。
步驟二、數據集
【cd KNN】切換至KNN目錄下,【cp -R /home/soft/digits/ /home/KNN/】將數據從/home/soft目錄下拷貝至/home/KNN目錄下,【cd digits】切換至數據目錄下查看,該目錄下分別放置訓練數據集和測試數據集的文件夾。如圖5所示。
【cd testDigits】切換至測試數據集的文件夾中查看,全部的文本格式存儲的數字文件命名格式爲:數字的值_該數字的樣本序號。訓練數據集和測試數據集是同樣的格式。可自行查看。如圖6所示。
每個文本中都包含32像素x32像素的數字。可經過【cat】命令查看任意文件。如圖7所示。
步驟三、K-近鄰算法
【cd ../..】切換至KNN目錄下,【vim kNN_digits.py】回車後建立並編輯名爲kNN_digits的Python文件。如圖8所示。
回車後進入編輯框內,按鍵盤【i】進入編輯狀態,編譯以下程序。如圖9所示。
【import numpy as np】導入numpy矩陣庫
【import operator】導入運算符模塊
【from os import listdir】導入os模塊,操做文件夾
【from sklearn.neighbors import KNeighborsClassifier as kNN】導入sklearn庫
將32x32的二進制圖像轉換爲1x1024向量。如圖10所示。
建立手寫數字分類測試函數hangwritingClassTest,分別獲得訓練集訓練的矩陣及類別,經過sklear的KNN近鄰算法訓練模型。如圖11所示。
在hangwritingClassTest內繼續獲得測試數據集的矩陣,經過neigh.predict對測試數據進行預測。最後經過出現的錯誤數除以總的個數獲得錯誤率。如圖12所示。
在main函數內調用hangwritingClassTest函數。如圖13所示。
編輯完畢後,按【esc】退出編輯狀態,【:wq】保存並退出編輯框,【python kNN_digits.py】執行kNN_digits的Python文件,結果以實際預測爲準。如圖14所示。
步驟四、源碼
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()