KNN-分類算法

一.什么叫KNN

KNN,K-NearestNeighbor,即K個(gè)最近的鄰居的意思。對(duì)于一個(gè)輸入樣本,用特征上最接近它的K個(gè)臨近值大多數(shù)屬于的標(biāo)簽來對(duì)它進(jìn)行分類。KNN是最簡單的機(jī)器學(xué)習(xí)算法之一,可以用于分類和回歸,是一種監(jiān)督學(xué)習(xí)算法。

二.KNN的過程介紹

具體實(shí)現(xiàn)過程如下:
①準(zhǔn)備數(shù)據(jù),對(duì)數(shù)據(jù)進(jìn)行預(yù)處理


預(yù)處理

在已經(jīng)分好類的情況下,我們需要對(duì)沒有分類的物品進(jìn)行分類 。
②計(jì)算測試樣本點(diǎn)(也就是待分類點(diǎn))到其他每個(gè)樣本點(diǎn)的距離。


距離計(jì)算

要度量空間中點(diǎn)距離的話,有好幾種度量方式,比如常見的曼哈頓距離計(jì)算,歐式距離計(jì)算等等。不過通常KNN算法中使用的是歐式距離,這里只是簡單說一下,拿二維平面為例,,二維空間兩個(gè)點(diǎn)的歐式距離計(jì)算公式如下:
二維空間歐式距離

其實(shí)就是計(jì)算(x1,y1)和(x2,y2)的距離。拓展到多維空間,則公式變成這樣:


多維空間歐式距離

這樣我們就明白了如何計(jì)算距離,KNN算法最簡單粗暴的就是將預(yù)測點(diǎn)與所有點(diǎn)距離進(jìn)行計(jì)算
③對(duì)每個(gè)距離進(jìn)行排序,然后選擇出距離最小的K個(gè)點(diǎn) 。
距離排序

④對(duì)K個(gè)點(diǎn)所屬的類別進(jìn)行比較,根據(jù)少數(shù)服從多數(shù)的原則,將測試樣本點(diǎn)歸入在K個(gè)點(diǎn)中占比最高的那一類
我們將K值取3,可以看出,距離其最近的三個(gè)點(diǎn)的投票結(jié)果是:
A類物品 2
B類物品 1
所以我們可以將需要識(shí)別物品歸類于A類物品

三.K值的選擇

k值是KNN算法的一個(gè)參數(shù),K的含義即參考”鄰居“標(biāo)簽值的個(gè)數(shù)。
如果當(dāng)K的取值過小時(shí),一旦有噪聲得成分存在們將會(huì)對(duì)預(yù)測產(chǎn)生比較大影響,例如取K值為1時(shí),一旦最近的一個(gè)點(diǎn)是噪聲,那么就會(huì)出現(xiàn)偏差,K值的減小就意味著整體模型變得復(fù)雜,容易發(fā)生過擬合;
如果K的值取的過大時(shí),就相當(dāng)于用較大鄰域中的訓(xùn)練實(shí)例進(jìn)行預(yù)測,學(xué)習(xí)的近似誤差會(huì)增大。這時(shí)與輸入目標(biāo)點(diǎn)較遠(yuǎn)實(shí)例也會(huì)對(duì)預(yù)測起作用,使預(yù)測發(fā)生錯(cuò)誤。K值的增大就意味著整體的模型變得簡單;
如果K==N的時(shí)候,那么就是取全部的實(shí)例,即為取實(shí)例中某分類下最多的點(diǎn),就對(duì)預(yù)測沒有什么實(shí)際的意義了
在劃分好數(shù)據(jù)集后,我們可以通過交叉驗(yàn)證法來得到最佳的K值

四.KNN算法的優(yōu)缺點(diǎn)

優(yōu)點(diǎn):
1.無數(shù)據(jù)輸入假定,在分類完的情況下進(jìn)行測試
2.預(yù)測精度高
3.對(duì)異常值不敏感
缺點(diǎn):
1.時(shí)間復(fù)雜度和空間復(fù)雜度高,計(jì)算到每一個(gè)點(diǎn)的距離,計(jì)算量較大
2.當(dāng)樣本不平衡的時(shí)候,比如一個(gè)類的樣本容量大,另一個(gè)類的樣本容量很小,對(duì)于測試識(shí)別的樣本來說,投票結(jié)果更容易靠近樣本容量大的類,從而導(dǎo)致分類錯(cuò)誤

五.KNN算法簡單代碼實(shí)現(xiàn)

#---------------------------------------引用庫-----------------------------------#
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import math
#---------------------------------------測試集-----------------------------------#
train_x=[12,15,24,56,68,90]
train_y=[50,59,67,101,115,123]
#---------------------------------------訓(xùn)練集-----------------------------------#
test_x=[40]
test_y=[72]
#--------------------------------------分類標(biāo)簽----------------------------------#
labels=['A','A','A','B','B','B']
#--------------------------------------繪制圖像----------------------------------#
def runplt():
    plt.figure()
    plt.title("train data ")
    plt.xlabel('x data')
    plt.ylabel('y data')
    plt.grid(True)
    plt.xlim(0, 100)
    plt.ylim(0, 150)
    return plt
dia = train_x
price = train_y
print(dia)
print(price)
plt = runplt()
plt.plot(dia, price, 'k.')
plt.scatter(test_x,test_y,color='b')
plt.show()
#-------------------------------------距離計(jì)算------------------------------------#
distance=[]
len1=len(test_x)
len2=len(train_x)
for i in range(len1):
    for j in range(len2):
        derta_x=abs(train_x[j]-test_x[i])
        derta_y=abs(train_y[j]-test_y[i])
        distance.append(pow(pow(derta_x,2)+pow(derta_y,2),0.5))
#-------------------------------- 輸出排序結(jié)果------------------------------------#
print (np.argsort(distance)) # 正序輸出索引,從小到大
for i in range(len(labels)):
    print(labels[np.argsort(distance)[i]])
#--------------------------------進(jìn)行投票表決-------------------------------------#
A=0
B=0
for i in range(int(len(labels)/2)):
    if labels[np.argsort(distance)[i]] == 'A':
        A+=1
    if labels[np.argsort(distance)[i]] == 'B':
        B+=1
print(A)
print(B)
if A>B:
    test_data_label='A'
if A<B:
    test_data_label='B'
#--------------------------------輸出分類結(jié)果-------------------------------------#
test_data_label
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容