K 最近鄰分類演算法 KNN 及python實現

2021-09-25 16:13:35 字數 3217 閱讀 8636

問題:確定綠色圓是屬於紅色三角形、還是藍色正方形?

knn的思想:

從上圖中我們可以看到,圖中的資料集是良好的資料,即都打好了label,一類是藍色的正方形,一類是紅色的三角形,那個綠色的圓形是我們待分類的資料。

如果k=3,那麼離綠色點最近的有2個紅色三角形和1個藍色的正方形,這3個點投票,於是綠色的這個待分類點屬於紅色的三角形

如果k=5,那麼離綠色點最近的有2個紅色三角形和3個藍色的正方形,這5個點投票,於是綠色的這個待分類點屬於藍色的正方形

即如果乙個樣本在特徵空間中的k個最相鄰的樣本中,大多數屬於某乙個類別,則該樣本也屬於這個類別。我們可以看到,knn本質是基於一種資料統計的方法!其實很多機器學習演算法也是基於資料統計的。

knn即k-nearest neighbor,是一種memory-based learning,也叫instance-based learning,屬於lazy learning。即它沒有明顯的前期訓練過程,而是程式開始執行時,把資料集載入到記憶體後,不需要進行訓練,就可以開始分類了。

knn也是一種監督學習演算法,通過計算新資料與訓練資料特徵值之間的距離,然後選取k(k>=1)個距離最近的鄰居進行分類判(投票法)或者回歸。若k=1,新資料被簡單分配給其近鄰的類。

1)計算測試資料與各個訓練資料之間的距離;

(計算距離的方式前文講k-means時說過,不清楚的可以去檢視以下➡傳送門)

2)按照距離的遞增關係進行排序;

3)選取距離最小的k個點;

k值是由自己來確定的

4)確定前k個點所在類別的出現頻率;

5)返回前k個點**現頻率最高的類別作為測試資料的**分類。

說明:對於步驟5的**分類有以下兩種方法

多數表決法:多數表決法類似於投票的過程,也就是在 k 個鄰居中選擇類別最多的種類作為測試樣本的類別。

加權表決法:根據距離的遠近,對近鄰的投票進行加權,距離越近則權重越大,通過權重計算結果最大值的類為測試樣本的類別。

非引數統計方法:不需要引入引數

k的選擇:

k = 1時,將待分類樣本劃入與其最接近的樣本的類。

k = |x|時,僅根據訓練樣本進行頻率統計,將待分類樣本劃入最多的類。

k需要合理選擇,太小容易受干擾,太大增加計算複雜性。

演算法的複雜度:維度災難,當維數增加時,所需的訓練樣本數急劇增加,一般採用降維處理。

簡單、有效。

重新訓練的代價較低(類別體系的變化和訓練集的變化,在web環境和電子商務應用中是很常見的)。

計算時間和空間線性於訓練集的規模(在一些場合不算太大)。

由於knn方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,knn方法較其他方法更為適合。

該演算法比較適用於樣本容量比較大的類域的自動分類,而那些樣本容量較小的類域採用這種演算法比較容易產生誤分。

knn演算法是懶散學習方法(lazy learning),而一些積極學習的演算法要快很多。

需要儲存全部的訓練樣本

輸出的可解釋性不強,例如決策樹的可解釋性較強。

該演算法在分類時有個主要的不足是,當樣本不平衡時,如乙個類的樣本容量很大,而其他類樣本容量很小時,有可能導致當輸入乙個新樣本時,該樣本的k個鄰居中大容量類的樣本占多數。該演算法只計算最近的鄰居樣本,某一類的樣本數量很大,那麼或者這類樣本並不接近目標樣本,或者這類樣本很靠近目標樣本。無論怎樣,數量並不能影響執行結果。可以採用權值的方法(和該樣本距離小的鄰居權值大)來改進。

計算量較大。目前常用的解決方法是事先對已知樣本點進行剪輯,事先去除對分類作用不大的樣本。

廢話不多說,咱直接上圖:

相似點:

雖然兩者有很大且別,但兩者也有共同之處。都包含了乙個過程:給定乙個點,在資料集找離它最近的點,即都用到了nn(nearest neighbor)演算法。

下面引入乙個例項,通過python**具體看下knn演算法的流程。

from numpy import *

import operator

dataset = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])

labels = ['a','a','b','b']

def classify0(inx,dataset,labels,k):

#求出樣本集的行數,也就是labels標籤的數目

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()

#對距離最小的k個點統計對應的樣本標籤

classcount = {}

for i in range(k):

#取第i+1鄰近的樣本對應的類別標籤

voteilabel = labels[sorteddistindicies[i]]

#以標籤為key,標籤出現的次數為value將統計到的標籤及出現次數寫進字典

classcount[voteilabel] = classcount.get(voteilabel,0) + 1

#對字典按value從大到小排序

sortedclasscount = sorted(classcount.items(),key=operator.itemgetter(1),reverse=true)

#返回排序後字典中最大value對應的key

return sortedclasscount[0][0]

if __name__ == '__main__':

print(classify0([1.1,0],dataset,labels,3))

K近鄰(KNN) 分類演算法

k近鄰 knn 分類演算法 knn是non parametric分類器 不做分布形式的假設,直接從資料估計概率密度 是memory based learning.knn不適用於高維資料 curse of dimension machine learning的python庫很多,比如mlpy 更多pa...

KNN最近鄰分類演算法梳理

k最近鄰 knn,k nearestneighbor 分類演算法是資料探勘分類技術中最簡單的方法之一。其指導思想是 近朱者赤,近墨者黑 即由你的鄰居來推斷出你的類別。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。knn最鄰近分類演算法的實現原理 為了判斷未知...

K最近鄰(KNN)演算法(二)

2.待補充 通過knn演算法的實踐中,樣本的不同特徵的單位不同,會在求距離時造成很大的影響。比如 在兩個樣本中腫瘤大小的分別為1cm和5cm,發現時間分別為100天和200天,那麼在求距離時,時間差為100 大小差為4,那麼其結果會被時間所主導,因為腫瘤大小的差距太小了。但是如果我們把時間用年做單位...