機器學習-簡單介紹入門算法kNN

基於Peter Harrington所著《Machine Learning in Action》python

 

kNN,即k-NearestNeighbor算法,是一種最簡單的分類算法,拿這個當機器學習、數據挖掘的入門實例是很是合適的。算法

 

簡單的解釋一下kNN的原理和目的:數組

假設有一種數據,每一條有兩個特徵值,這些數據總共有兩大類,例如:機器學習

[ [1 , 1.1] , [ 1 , 1 ] , [0 , 0 ] , [0 , 0.1] ] 這四個數據(訓練數據),種類分別爲[ 'A' , 'A' , 'B' ,'B' ]。學習

如今給出一條數據X=[1.1 , 1.1],須要判斷這條數據屬於A仍是B,這時候就能夠用kNN來判斷。固然現實中每一個數據可能有不少個特徵,總共也有不少分類,這裏以最簡單的方式來舉例。測試

原理也很是簡單,將上述訓練數據放到座標軸中,而後計算X到每一個訓練數據的距離,從近到遠作個排序,選取其中的前N條,判斷其中是屬於A類的數據多仍是B類的多,若是屬於A類的多,那能夠認爲X屬於A;反之亦然。spa

 

下面就用具體的代碼來演示一下上面陳述的算法。(基於py,建議直接裝anaconda,一勞永逸)rest

創建一個py文件,名稱隨意。code

先是建立訓練數據,這裏用py數組代替,實際多是一堆文本或其餘格式blog

def createDataSet(): group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]) lables=['A','A','B','B'] return group,lables

group是訓練數據,lables是group的分類數據。

 

kNN算法

 1 def classify0(inX,dataSet,labels,k):  2     dataSetSize = dataSet.shape[0]  3     diffMat=tile(inX,(dataSetSize,1))-dataSet  4     sqDiffMat=diffMat**2
 5     sqDistances= sqDiffMat.sum(axis=1)  6     distances = sqDistances**0.5
 7     sortedDistIndicies = distances.argsort()  8     classCount={}  9     for i in range(k): 10         voteIlabel = labels[sortedDistIndicies[i]] 11         classCount[voteIlabel]=classCount.get(voteIlabel,0)+1
12     sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True) 13     return  sortedClassCount[0][0]

 

inX就是須要判斷的數據X,dataSet就是上面構建出來的group,labels是group的分類,k是「從近到遠作個排序,選取其中的前N條」中的N,這個會對結果的準確性有必定影響。

這裏用如下測試數據結合kNN算法進行講解。

group,labels = createDataSet() inX= [1.1,1.10] print(classify0(inX,group,labels,3))

 

第2行是計算dataSet的總行數,此時爲4。下面3,4,5,6行就是計算inX到每一個訓練數據的距離的,用的是歐式距離公式0ρ = sqrt( (x1-x2)^2+(y1-y2)^2 ),高中都學過。只是用矩陣和python的形式寫出來可能一時很差看明白。

 

 

3 tile(inX,(dataSetSize,1)) 構建出一個每一行都是inX,有dateSetSize行的矩陣,具體數據以下:

[[ 1.1  ,1.1]
[ 1.1  ,1.1]
[ 1.1  ,1.1]
[ 1.1  ,1.1]]

再用這個矩陣減去dataSet,則會獲得inX和每一個訓練數據的x,y座標上的差值。最終的diffMat以下,這就是inX對每一個訓練數據的 x1-x2,y1-y2:

[[ 0.1  ,0. ]
[ 0.1  ,0.1]
[ 1.1  ,1.1]
[ 1.1  ,1. ]]

4就是對矩陣作個平方,獲得結果以下,即(x1-x2)^2,(y1-y2)^2:

[[ 0.01  ,0. ]
[ 0.01  ,0.01]
[ 1.21  ,1.21]
[ 1.21  ,1. ]]

5就是把矩陣橫向相加,獲得結果就是(x1-x2)^2+(y1-y2)^2:

[ 0.01  ,0.02 , 2.42,  2.21]

6就是對5獲得的(x1-x2)^2+(y1-y2)^2進行開根號,獲得inX到每一個訓練數據的距離,結果以下:

[ 0.1  ,       0.14142136 , 1.55563492 , 1.48660687]

 

7是對6作個排序,9-11就是選出和inX距離最近的前k個點,統計這k個點中有幾個屬於A,有幾個屬於B。在本例中,獲得的sortedClassCount爲:

 [('A', 2), ('B', 1)]

也就是和inX最近的三個點有兩個屬於A,一個B。這是,就能夠認爲inX是屬於A類的了。

相關文章
相關標籤/搜索