監督學習——K鄰近算法及數字識別實踐


1. KNN 算法

        K-近鄰(k-Nearest Neighbor,KNN)是分類算法,是一個理論上比較成熟的方法,也是最簡單的機器學習算法之一。該方法的思路是:如果一個樣本在特征空間中的k個最相似(即特征空間中最鄰近)的樣本中的大多數屬於某一個類別,則該樣本也屬於這個類別。

         K鄰近算法原理很簡單,但是真正用好它也不容易,比如K的取值到底為多少才合適,而且知道什么場景下用它更不簡單。

         缺點:  該算法的執行效率並不高,每次計算都需要將 待識別的用例 與所有測試用例進行求差計算,計算量較大。隨着測試數據的增多,計算量會越來越大。

2. 數字識別 Python 實現

        下圖為一個 二進制表示的數字“6”,每個訓練數據和測試數據都是以這種形式保存在一個txt文件中,數據為32*32(1024個數據)的矩陣。

20171230175900503

 

KNN算法實現數字識別步驟

1. 讀取訓練數據中的所有數據到一個矩陣中(矩陣中的每一列代表一個圖片數據),同時讀取數據的標簽保存在一個數組中(數據的標簽或患者說文件代表的具體數字信息在文件命中)

2. 讀取測試數據,轉換1024*1的矩陣。

3. 用測試數據與矩陣A中的每一列求距離,求得的L個距離存入距離數組中(距離算法)

4. 從距離數組中取出最小的K個距離所對應的訓練集的索引

5. 擁有最多索引的值就是預測值(有多個眾數時,按距離和最小)

數據加載函數

該函數用於打開一個數字數據源(32*32),保存在一個1*1024的矩陣中

def openFile(fileName):
    returnVect = np.zeros((1,1024))
    fr = open(fileName)
    for i in range(32):
        linestr = fr.readline();
        for j in range(32):
            returnVect[0,32*i+j] = int(linestr[j])
    return returnVect

如果需要加載某個文件夾下的所有數字文件則可以調用如下函數(數字的標簽保存在文件名中第一個字符)

def loadData(dir):
    fileList = listdir(dir)  // 列出dir文件下的所有文件(測試數據)
    lable = []
    index = 0
    dataMat = np.zeros((1024,len(fileList)))
    for file in fileList:
        lable.append(int(file[0]));  // 標簽信息保存在文件的第一個字符中
        dataMat[:,index] = openFile(dir+file)
        index +=1;
    return dataMat,lable

距離計算函數

該函數用於計算兩個圖片舉證(1*1024)的距離,(相同位置如果數字相同則距離加1)

def caculateerro(data1,data2):
    len1 = len(data1)
    len2 = len(data2)
    sizelen = min(len1,len2);
    totalerro = 0;
    for i in range(sizelen):
        if data1[i] != data2[i]:
            totalerro +=1
    return totalerro

數字識別函數

def classFier(datain):
    k=15
    dictErro = {} //保存 訓練數據編號——測試數據與該訓練數據的距離
    trainingdata, traninglabel = loadData('digits\\trainingDigits\\');
    m,n = trainingdata.shape;

    for i in range(n):
        // 計算測試圖片與每張訓練圖片的距離
        currErro = caculateerro(datain,trainingdata[:,i])
        dictErro[i] = currErro
    sortedDict = sorted(dictErro.items(),key=lambda x:x[1],reverse=False);
    numofnumber = range(10)

    for i in range(10):
        numofnumber[i] = 0
    for j in range(30):
        label = int(sortedDict[j][0])
        numofnumber[int(traninglabel[label])] += 1;
    return numofnumber.index(max(numofnumber))

        上述源碼中KNN算法的K取值為15,即取出距離訓練數據最小的十五個圖片,然后判斷這15張圖片中對應的那個數字出現的平率最多,將最多的數據作為識別結果返回。

 

參考:

《機器學習實戰》

https://blog.csdn.net/zzz_cming/article/details/78938107


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM