【機器學習 2】k-鄰近算法識別手寫數字

思路:
訓練集:trainingDigits文件夾內的32位二進制圖像矩陣
Target向量:從trainingDigits文件夾內的文件名讀取圖像矩陣所表示的數字
測試集:testDigits文件夾內的32位二進制圖像矩陣
predicted預測值:從testDigits文件夾內文件名讀取圖像矩陣所表示的數字

#手寫識別系統
#(1)收集數據:提供文本文件
#(2)準備數據:編寫函數img2vector(),將圖像格式轉換爲分類器使用的向量格式
#(3)分析數據:在Anancode中檢查數據,確保它凡符合要求
#(4)訓練算法:不適用於k-近鄰算法
#(5)測試算法:編寫函數,使用提供的部分數據集作爲測試樣本,測試樣本與非測試樣本的區
        # 別在於測試樣本已經完成分類的數據,如果預測分類與實際分類不同,則標記爲一個錯誤
#(6)使用算法:本例沒有完成此步驟,若你感興趣可以構建完整的應用程序,從圖像中提取數字,
    # 並完成數字識別,美國的郵件分揀系統就是一個實際運行的類似系統。

#準備數據:將圖像轉換爲測試向量
#原數據爲 32*32的二進制圖像矩陣,轉化爲 1*1024的向量
import numpy as np
import operator
from os import listdir

def classify(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = np.tile(inX,(dataSetSize,1)) - dataSet
    sqDiffMat = diffMat ** 2
    sqDistance = sqDiffMat.sum(axis = 1)
    distance = sqDistance ** 0.5
    sortAsDistance = distance.argsort()
    classCount = {}
    for i in range(k):
        voteIlabel = labels[sortAsDistance[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) +1
    sortDeclassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
    return sortDeclassCount[0][0]

def imgvector(filename):
    returnVec = np.zeros((1,1024))
    fr = open(filename)
    for i in range(32):
        lineStr = fr.readline()
        for j in range(32):
            returnVec[0,32*i+j]=int(lineStr[j])
    return returnVec

#測試算法:使用k-近鄰算法識別手寫數字


def handwritingClassTest():
    hwLabels = []
    traningFileList = listdir('trainingDigits')
    #os.listdir() 方法用於返回指定的文件夾包含的文件或文件夾的名字的列表。這個列表以字母順序。 它不包括 '.' 和'..' 即使它在文件夾中。
    #只支持在 Unix, Windows 下使用。
    m = len(traningFileList)
    trainingMat = np.zeros((m,1024)) #建立矩陣用於存儲讀取的數據
    for i in range(m):
        fileNameStr = traningFileList[i]
        fileStr = fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0]) #以'_'爲分隔符分割文件名稱元素,並取第一個值
        hwLabels.append(classNumStr)
        trainingMat[i,:] = imgvector('trainingDigits/%s' % fileNameStr)
   #上述程序,建立了矩陣 hwLabels 用於存放每個文件名的第一個字符,即0~9,對應文件內的圖像矩陣
    #建立了數據集 trainingMat 存放樣本數據
    testFileList = listdir('testDigits')
    errorCount = 0.0
    mTest = len(testFileList)
    for i in range(mTest):
        fileNameStr = testFileList[i]
        fileStr = fileNameStr.split('.')[0]
        classNumStr = int(fileStr.split('_')[0])
        vectorUnderTest = imgvector('testDigits/%s' % fileNameStr)
        classifierResult = classify(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("The total error rate is :%f" % (errorCount/mTest))

發佈了34 篇原創文章 · 獲贊 23 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章