1. 程式人生 > >機器學習(一)k-進鄰演算法

機器學習(一)k-進鄰演算法

k-進鄰演算法

概述

原理

存在一個樣本資料集合,也稱作為訓練樣本集,並且樣本集中每個資料都存在標籤,即我們知道樣本集中每一個數據與所屬分類的對應關係。輸入沒有標籤的新資料後,將新的資料的每個特徵與樣本集中資料對應的特徵進行比較,然後演算法提取樣本最相似資料(最近鄰)的分類標籤。一般來說,我們只選擇樣本資料集中前k個最相似的資料,這就是k-近鄰演算法中k的出處,通常k是不大於20的整數。最後,選擇k個最相似資料中出現次數最多的分類,作為新資料的分類。

步驟

  1. 計算已知類別資料集中的點與當前點之間的距離;
  2. 按照距離遞增次序排序;
  3. 選取與當前點距離最小的k個點;
  4. 確定前k個點所在類別的出現頻率;
  5. 返回前k個點所出現頻率最高的類別作為當前點的預測分類。

相關公式(歐氏距離)

核心程式碼如下

def classify0(inX, dataSet, labels, k):
    dataSetSize = dataSet.shape[0]
    diffMat = tile(inX, (dataSetSize,1)) - dataSet
    sqDiffMat = diffMat**2
    sqDistances = sqDiffMat.sum(axis=1)
    distances = sqDistances**0.5
    sortedDistIndicies = distances.argsort()     
    classCount={}          
    for i in range(k):
        voteIlabel = labels[sortedDistIndicies[i]]
        classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
    sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)
    return sortedClassCount[0][0]

注意事項

資料要做歸一化,要不其中一項的影響會特別大

比如距離的範圍0到5000,年齡範圍0到100,在算距離的時候,距離這個特徵產生的影響遠遠比年齡大,導致年齡這個特徵不起作用,正確做法是把所有特徵變為【0,1】之間,python程式碼如下

def autoNorm(dataSet):
    minVals = dataSet.min(0)
    maxVals = dataSet.max(0)
    ranges = maxVals - minVals
    normDataSet = zeros(shape(dataSet))
    m = dataSet.shape[0]
    normDataSet = dataSet - tile(minVals, (m,1))
    normDataSet = normDataSet/tile(ranges, (m,1))   #element wise divide
    return normDataSet, ranges, minVals

簡單例子

判斷一個電影是愛情片還是武打片,取兩個特徵打鬥鏡頭和接吻鏡頭,由於這兩個特徵是否歸一化影響不大,所以這裡忽略歸一化,有了這四個訓練集,現在測試資料有一部電影打鬥鏡頭101次,接吻鏡頭20次,是什麼型別的電影

 通過計算,我們可以得到如下結果:

(101,20)->動作片(108,5)的距離約為16.55
(101,20)->動作片(115,8)的距離約為18.44
(101,20)->愛情片(5,89)的距離約為118.22
(101,20)->愛情片(1,101)的距離約為128.69
 

通過計算可知,電影到動作片 (108,5)的距離最近,為16.55。如果演算法直接根據這個結果,判斷該紅色圓點標記的電影為動作片,這個演算法就是最近鄰演算法,而非k-近鄰演算法。k-近鄰演算法,我們假設k=3,也就是取距離最近前三個的最大值作為其結果,最近的前三個為

動作片(108,5)的距離約為16.55

動作片(115,8)的距離約為18.44

愛情片(5,89)的距離約為118.22

裡面出現動作片次數2大於愛情片1,所以(101,20)利用k-進鄰演算法的結果是動作片
喜歡的小夥伴可以給個贊哦