1. 程式人生 > >K-近鄰演算法(KNN)

K-近鄰演算法(KNN)

     拜讀大神的系列教程,大神好像姓崔(猜測),大神根據《機器學習實戰》來講解,講的很清楚,讀了大神的部落格後,我也把我自己吸收的寫下來,可能有很多錯誤之處,希望拍磚(拍輕點)

    大神部落格: https://cuijiahua.com/blog/2017/11/ml_1_knn.html  ,寫得很好

   話不多說:

   前言:

  KNN演算法應該是最簡單的方法了(估計沒有之一),在講KNN理論之前,先講下學校時學的兩點間距離公式,即:

  

           注: 這是2維座標系裡,求兩點距離

   一、KNN理論

  首先我們有兩個資料集,訓練集和測試集,訓練集用來訓練資料,測試集用來測試訓練後的準確性 

 

  有了兩點間距離公式,接下來說下KNN步驟:

  (1)、首先準備訓練集

  (2)、準備測試集

  (3)、求測試集和訓練集每點之間的距離

  (4)、按距離升序排序

  (5)、取前K個數據(K一般為奇數較好),讀取每個資料的分類結果

  (6)、計算每個分類出現的次數

  以上是KNN大概步驟,可能光文字描述比較難懂點,其實核心就是兩點間距離公式,下面就用具體的例子說明:

二、首先我們舉一個電影分類的例子

  首先我們看下訓練集:

打鬥鏡頭數 接吻鏡頭數 分類結果
1 101 愛情片
 105  1  動作片
2 100 愛情片
100 1 動作片

  訓練集解釋:電影的分類只有兩個類別,即動作片和愛情片,而分類的根據是打鬥鏡頭數和接吻鏡頭數, 如果打鬥鏡頭比接吻鏡頭多,說明是愛情片(大家都懂的),反之則是動作片,這就是分類的規則,但大家有沒有發現一個問題,如果打鬥鏡頭和接吻鏡頭一樣多,那這個分類究竟是動作片還是愛情片了,還是愛情動作片? 其實這時候用KNN演算法是分辨不出來的,因為資料集沒有這個分類

       好了,訓練集準備好了,接下來看下測試集:

打鬥鏡頭數 接吻鏡頭數
130 1
1 100

  以上是其實是兩個測試集,下面就要分別求出分類結果:

  程式碼如下 

 1 import numpy as np;
 2 import operator;
 3 
 4 def createDataSet():#建立資料集
 5     group=np.array([[1,101],[5,89],[108,5],[115,8]]);#訓練集特徵
 6     labels=np.array(['愛情片','愛情片','動作片','動作片']);#訓練對應的結果
 7     return group,labels;
 8 
 9 def classisfy0(inx,dataSet,labels,k):#分類函式,即求出分類結果
10     dataSetSize=dataSet.shape[0];#獲得訓練集的行數
11     diffMat=np.tile(inx,(dataSetSize,1))-dataSet;#把測試集重複訓練集的行數,並且測試集減去訓練集,即(x1-x2),(y1-y2)
12     sqDiffMat=diffMat**2;#對矩陣每個元素求平方
13     sqDistance=sqDiffMat.sum(axis=1);#對矩陣按行求和,axis=1即按行求和
14     distance=sqDistance**0.5;#對求和後的矩陣,開方根,即距離公式的開方
15     sortedDistIndices=distance.argsort();#求出來的距離按從小大到排序,並且返回每個元素的索引,這裡要注意的是:排序後的元素索引不會變,還是原來的索引,不瞭解的可以百度下argsort函式
16     classCount={};
17     for i in range(k):#取前K個值,並且計算出每個分類出現的次數
18         votelabel=lables[sortedDistIndices[i]];
19         classCount[votelabel]=classCount.get(votelabel,0)+1;
20     #排序,即按出現次數從大到小排序
21     sortedClassCount=sorted(classCount.items(),key=operator.itemgetter(1),reverse=True);
22     return sortedClassCount[0][0];#取第一個元素的分類結果,即出現次數最多的分類就是分類結果
23 
24 if __name__=='__main__':
25     group,lables=createDataSet();
26     test=[130,1];#測試集1
27     test_class=classisfy0(test,group,lables,3);
28     print('測試集1結果:',test_class);
29     test=[1,100];#測試集2
30     test_class = classisfy0(test, group, lables, 3);
31     print('測試集2結果:',test_class)

 

  執行結果截圖:

  

   以上就是KNN的示例

 

三、根據約會資料集計算出約會成功的概率

  前言:大家有沒有想到一個問題,如果我的資料集是多維的,那距離怎麼求了,這就是另一個公式了,即歐氏距離公式,即:

  

    先講到這裡吧,下篇再講怎麼計算多維度的資料集分類,大家也可以根據上面電影分類來實現!

   以上都是我看崔大神的部落格:https://cuijiahua.com/blog/2017/11/ml_1_knn.html,學習到的,可能有些地方理解有錯誤,歡迎指教!

&n