Python 基於KNN算法的手寫識別系統
阿新 • • 發佈:2017-06-17
res eight mon -s 利用 filename setsize http 需要 本文主要利用k-近鄰分類器實現手寫識別系統,訓練數據集大約2000個樣本,每個數字大約有200個樣本,每個樣本保存在一個txt文件中,手寫體圖像本身是32X32的二值圖像,如下圖所示:
手寫數字識別系統的測試代碼:
from numpy import *
import operator
from os import listdir
#inX 要檢測的數據
#dataSet 數據集
#labels 結果集
#k 要對比的長度
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0] #計算有多少行
# tile(inX, (dataSetSize,1))生成對應inX維度的矩陣,方便做差
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2 #差求平方
sqDistances = sqDiffMat.sum(axis=1) # axis=0, 表示列 axis=1, 表示行。
distances = sqDistances**0.5 #開方
sortedDistIndicies = distances.argsort() #argsort()排序,求下標
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]] #通過下標索引分類
# 通過構造字典,記錄分類頻數
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
# 對字段按值排序(從大到小)
sortedClassCount = sorted(classCount.items(),key=lambda classCount:classCount[1], reverse=True)
return sortedClassCount[0][0]
#手寫字體識別
#首先,我們需要將圖像格式化處理為一個向量,
# 把一個32X32的二進制圖像矩陣通過img2vector()函數轉換為1X1024的向量:
def img2vector(filename):
returnVect = zeros((1,1024))
fr = open(filename)
for i in range(32): #圖片矩陣為32*32
lineStr = fr.readline() #數據量大,所以使用readline
for j in range(32):
returnVect[0,32*i+j] = int(lineStr[j])
return returnVect
#手寫字體識別
def handwritingClassTest():
hwLabels = []
trainingFileList = listdir(r‘trainingDigits‘) #指定文件夾
m = len(trainingFileList) #獲取文件夾個數
trainingMat = zeros((m,1024)) #構造m個1024比較矩陣
for i in range(m):
fileNameStr = trainingFileList[i] #獲取文件名
fileStr = fileNameStr.split(‘.‘)[0] #按點把文件名字分割
classNumStr = int(fileStr.split(‘_‘)[0]) #按下劃線把文件名字分割
hwLabels.append(classNumStr) #實際值添加保存
trainingMat[i,:] = img2vector(r‘trainingDigits/%s‘ % fileNameStr)
testFileList = listdir(‘testDigits‘) #測試數據
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):#同上,處理測試數據
fileNameStr = testFileList[i]
fileStr = fileNameStr.split(‘.‘)[0] #take off .txt
classNumStr = int(fileStr.split(‘_‘)[0])
vectorUnderTest = img2vector(r‘testDigits/%s‘ % fileNameStr)
classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
print ("計算值: %d, 實際值: %d" % (classifierResult, classNumStr))
if (classifierResult != classNumStr): errorCount += 1.0
print ("\n錯誤出現次數: %d" % errorCount)
print ("\n錯誤率: %f" % (errorCount/float(mTest)))
handwritingClassTest()
結果:
計算值: 9, 實際值: 9
計算值: 9, 實際值: 9
計算值: 9, 實際值: 9
計算值: 9, 實際值: 9
計算值: 9, 實際值: 9
計算值: 9, 實際值: 9
錯誤出現次數: 10
錯誤率: 0.010571
可以看到KNN算法對內存消耗很大(本人12G),中文環境識別不敢想象。
Python 基於KNN算法的手寫識別系統