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