K 近鄰(KNN)演算法

2021-10-10 19:09:57 字數 3425 閱讀 1021

最簡單最初級的分類器是將全部的訓練資料所對應的類別都記錄下來,當測試物件的屬性和某個訓練物件的屬性完全匹配時,便可以對其進行分類。但是怎麼可能所有測試物件都會找到與之完全匹配的訓練物件呢,其次就是存在乙個測試物件同時與多個訓練物件匹配,導致乙個訓練物件被分到了多個類的問題,基於這些問題呢,就產生了knn。

knn是通過測量不同特徵值之間的距離進行分類。它的思路是:如果乙個樣本在特徵空間中的k個最相似(即特徵空間中最鄰近)的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別,其中k通常是不大於20的整數。knn演算法中,所選擇的鄰居都是已經正確分類的物件。該方法在定類決策上只依據最鄰近的乙個或者幾個樣本的類別來決定待分樣本所屬的類別。

下面通過乙個簡單的例子說明一下:如下圖,綠色圓要被決定賦予哪個類,是紅色三角形還是藍色四方形?如果k=3,由於紅色三角形所佔比例為2/3,綠色圓將被賦予紅色三角形那個類,如果k=5,由於藍色四方形比例為3/5,因此綠色圓被賦予藍色四方形類。

由此也說明了knn演算法的結果很大程度取決於k的選擇。

在knn中,通過計算物件間距離來作為各個物件之間的非相似性指標,避免了物件之間的匹配問題,在這裡距離一般使用歐氏距離或曼哈頓距離:

同時,knn通過依據k個物件中佔優的類別進行決策,而不是單一的物件類別決策。這兩點就是knn演算法的優勢。

接下來對knn演算法的思想總結一下:就是在訓練集中資料和標籤已知的情況下,輸入測試資料,將測試資料的特徵與訓練集中對應的特徵進行相互比較,找到訓練集中與之最為相似的前k個資料,則該測試資料對應的類別就是k個資料**現次數最多的那個分類,其演算法的描述為:

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

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

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

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

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

首先呢,需要說明的是我用的是python3.7.9,裡面有一些用法與2.7還是有些出入。

建立乙個knn.py檔案對演算法的可行性進行驗證,如下:

# coding:utf-8

from numpy import

*'''

numpy.tile(a,b)

>>> import numpy

>>> numpy.tile([0,0],5)#在列方向上重複[0,0]5列,預設行1次

array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])

numpy.tile([0,0],(2,1))#在列方向上重複[0,0]1次,行2次

array([[0, 0],

[0, 0]])

>>> numpy.tile([0,0],(1,3))#在列方向上重複[0,0]3次,行1次

array([[0, 0, 0, 0, 0, 0]])

>>> numpy.tile(0,(5,2))

array([[0, 0],

[0, 0],

[0, 0],

[0, 0],

[0, 0]])

''''''

a = np.array([[1,2],[3,4]])

按行相加,不保持其二維特性

print(np.sum(a, axis=1))

# 按行相加,並且保持其二維特性

print(np.sum(a, axis=1, keepdims=true))

array([3, 7])

array([[3], [7]])

'''# 給出訓練資料以及對應的類別

defcreatedataset()

: group = array([[

1.0,

2.0],[

1.2,

0.1],[

0.1,

1.4],[

0.3,

3.5]])

labels =

['a'

,'b'

,'c'

,'d'

]return group, labels

# 通過knn進行分類

defclassify

(input

, dataset, label, k)

: datasize = dataset.shape[0]

# 計算歐式距離

diff = tile(

input

,(datasize,1)

)- dataset

sqdiff = diff **

2# 表示diff的2次方

squaredist =

sum(sqdiff, axis=1)

# 行向量分別相加,從而得到新的乙個行向量

dist = squaredist **

0.5print

('歐式距離是:'

, dist)

# 對距離進行排序,以方便查詢訓練集中與之最為相似的前k個資料,

# 則該測試資料對應的類別就是k個資料**現次數最多的那個分類

sorteddistindex = argsort(dist)

# argsort()根據元素的值從小到大對元素進行排序,返回下標

classcount =

for i in

range

(k):

votelabel = label[sorteddistindex[i]

]# 對選取的k個樣本所屬的類別個數進行統計

classcount[votelabel]

= classcount.get(votelabel,0)

+1# 選取出現的類別次數最多的類別

maxcount =

0for key, value in classcount.items():

if value > maxcount:

maxcount = value

classes = key

return classes

if __name__ ==

'__main__'

: dataset, labels = createdataset(

)input

= array(

[1.2,8

])output = classify(

input

, dataset, labels,3)

print

("測試資料為:"

,input

,"分類結果為:"

, output)

答案符合我們的預期,要證明演算法的準確性,勢必還需要通過處理複雜問題進行驗證,之後再做研究。

K 近鄰演算法 KNN

knn k nearest neighbor 假設訓練集有記錄 r1 r2,rn共n條,訓練集的特徵向量及其對應的類別都是已知的,每個記錄的特徵向量為 t1 t2,tk共k個特徵,待測試的記錄為ru 1 計算ru 的特徵向量與訓練集的每條記錄 即r1 r2,rn 的特徵向量的歐式距離,選取距離最小的...

k近鄰演算法 kNN

核心思想 前k個最相似資料中出現次數最多的類別,作為新資料的類別。核心函式 計算距離函式,投票函式 coding utf 8 import random import sys from collections import counter from operator import itemgette...

K近鄰演算法 KNN

k近鄰演算法 knn 何謂k近鄰演算法,即k nearest neighbor algorithm,簡稱knn演算法,單從名字來猜想,可以簡單粗暴的認為是 k個最近的鄰居,當k 1時,演算法便成了最近鄰演算法,即尋找最近的那個鄰居。為何要找鄰居?打個比方來說,假設你來到乙個陌生的村莊,現在你要找到與...