Python 實現 KNN(K-近鄰)算法

 

1、概述

  KNN(K-最近鄰)算法是相對比較簡單的機器學習算法之一,它主要用於對事物進行分類。用比較官方的話來講就是:給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最鄰近的K個實例, 這K個實例的多數屬於某個類,就把該輸入實例分類到這個類中。爲了更好地理解,經過一個簡單的例子說明。算法

  咱們有一組自擬的關於電影中鏡頭的數據:機器學習

                         

  那麼問題來了,若是有一部電影 X,它的打戲爲 3,吻戲爲 2。那麼這部電影應該屬於哪一類?函數

  咱們把全部數據經過圖表顯示出來(圓點表明的是自擬的數據,也稱訓練集;三角形表明的是 X 電影的數據,稱爲測試數據):學習

                                   

  計算測試數據到訓練數據之間的距離,假設 k 爲 3,那麼咱們就找到距離中最小的三個點,假如 3 個點中有 2 個屬於動做片,1 個屬於愛情片,那麼把該電影 X 分類爲動做片。這種經過計算距離總結 k 個最鄰近的類,按照」少數服從多數「原則分類的算法就爲 KNN(K-近鄰)算法。測試

 

2、算法介紹

  仍是以上面的數據爲例,打戲數爲 x,吻戲數爲 y,經過歐式距離公式計算測試數據到訓練數據的距離,我上中學那會兒不知道這個叫作歐式距離公式,一直用」兩點間的距離公式「來稱呼這個公式: 。可是現實中的不少數據都是多維的,即便如此,也仍是按照這個思路進行計算,好比若是是三維的話,就在根號裏面再加上 z 軸差的平方,即 ,以此類推。spa

  知道了這個計算公式,就能夠計算各個距離了。咱們以到最上面的點的距離爲例:,那麼從上到下的距離分別是:。如今咱們把 k 定爲 3,那麼距離最近的就是後面三個數了,在這三個數中,有兩個屬於動做片,所以,電影 X 就分類爲動做片。code

 

3、算法實現

  知道了原理,那就能夠用代碼實現了,這裏就再也不贅述了,直接上帶註釋的 Python 代碼:blog

'''
    trainData - 訓練集
    testData - 測試集
    labels - 分類
'''
def knn(trainData, testData, labels, k):
    # 計算訓練樣本的行數
    rowSize = trainData.shape[0]
    # 計算訓練樣本和測試樣本的差值
    diff = np.tile(testData, (rowSize, 1)) - trainData
    # 計算差值的平方和
    sqrDiff = diff ** 2
    sqrDiffSum = sqrDiff.sum(axis=1)
    # 計算距離
    distances = sqrDiffSum ** 0.5
    # 對所得的距離從低到高進行排序
    sortDistance = distances.argsort()
    
    count = {}
    
    for i in range(k):
        vote = labels[sortDistance[i]]
        count[vote] = count.get(vote, 0) + 1
    # 對類別出現的頻數從高到低進行排序
    sortCount = sorted(count.items(), key=operator.itemgetter(1), reverse=True)
    
    # 返回出現頻數最高的類別
    return sortCount[0][0] 

  ps:np.tile(testData, (rowSize, 1)) 是將 testData 這個數據擴展爲 rowSize 列,這樣能避免運算錯誤;排序

    sorted(count.items(), key=operator.itemgetter(1), reverse=True) 排序函數,裏面的參數 key=operator.itemgetter(1), reverse=True 表示按照 count 這個字典的值(value)從高到低排序,若是把 1 換成 0,則是按字典的鍵(key)從高到低排序。把 True 換成 False 則是從低到高排序。get

 

 4、測試與總結

  用 Python 實現了算法以後,咱們用上面的數據進行測試,看一下結果是否和咱們預測的同樣爲動做片:

trainData = np.array([[5, 1], [4, 0], [1, 3], [0, 4]])
labels = ['動做片', '動做片', '愛情片', '愛情片']
testData = [3, 2]
X = knn(trainData, testData, labels, 3)
print(X)

  執行這段代碼後輸出的結果爲:動做片 。和預測的同樣。固然經過這個算法分類的正確率不可能爲 100%,能夠經過增長修改數據測試,若是有大量多維的數據就更好了。

相關文章
相關標籤/搜索