[機器學習實戰]kNN

原理

kNN(k近鄰算法)的基本思想就是選擇距離待分類點最近的K個點,統計這K個點中出現的分類的概率, 出現概率最高的分類即爲待分類點的分類

源碼

from numpy import *
import operator

def createDataSet():    # create data set
    group = array([[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]])
    labels = ['A', 'A', 'B', 'B']
    return group,labels

def classify0(inX, dataSet, labels, k): #k-NN classify
    """
    :param inX: 用於分類的輸入向量
    :param dataSet: 輸入的訓練樣本集
    :param labels: 標籤向量
    :param k: 用於選擇最近鄰居的數目
    :return:
    """

    # 用歐氏距離計算當前點與樣本集中所有點的距離
    dataSetSize = dataSet.shape[0]  #獲取數組維度的長度 (列或行數)
    diffMat = tile(inX, (dataSetSize, 1)) - dataSet # tile是重複次數,如tile([0,0],(2,3)),是在重複行2次,列3次,結果是[[0 0 0 0 0 0] [0 0 0 0 0 0]]
    sqDiffMat = diffMat ** 2    # 所有元素平方
    sqDistances = sqDiffMat.sum(axis = 1) # axis = none 表示所有元素相加, axis = 0表示每一列所有元素相加, axis = 1表示每一行所有元素相加
    distances = sqDistances**0.5    # 開方得到待求點到數據集中所有點的距離
    sortedDistIndicies = distances.argsort()    # 返回的是從小到大排序後的原數據的索引, 如原數據爲[1, 5, 3, 0], 調用argsort()方法返回的是[3, 0, 2, 1]
    classCount = {}

    # 選擇距離最小的k個點
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]] # 得到前k個標籤
        classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 # 統計label出現的次數,默認值爲0

    sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)  # 根據標籤出現次數從高到低排序
    return sortedClassCount[0][0]

if __name__ == "__main__":
    group, labels = createDataSet()
    result = classify0([0, 0], group, labels, 3)
    print(result)

加權kNN

有一個問題就是該算法給所有的近鄰分配相等的權重,這個還可以這樣改進,就是給更近的鄰居分配更大的權重(你離我更近,那我就認爲你跟我更相似,就給你分配更大的權重),而較遠的鄰居的權重相應地減少,取其加權平均。需要一個能把距離轉換爲權重的函數,gaussian函數是一個比較普遍的選擇,下圖可以看到gaussian函數的衰減趨勢。

高斯函數

這裏寫圖片描述

高斯函數的圖形在形狀上像一個倒懸着的鐘。參數a指高斯曲線的峯值,b爲其對應的橫座標,c即標準差(有時也叫高斯RMS寬值),它控制着“鍾”的寬度。

這裏寫圖片描述

交叉驗證

使用交叉驗證進行算法模型評估以及k值的選取

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章