KNN-算法原理+算法案例

一.算法原理
1.1 核心思想

kNN算法的核心思想是如果一個(gè)樣本在特征空間中的k個(gè)最相鄰的樣
本中的大多數(shù)屬于某一個(gè)類別,則該樣本也屬于這個(gè)類別,并具有
這個(gè)類別上樣本的特性。
一般來說,只選擇樣本數(shù)據(jù)集中前k個(gè)最相似的數(shù)據(jù),這就是k-近鄰
算法中k的出處,通常k是不大于20的整數(shù)。最后,選擇k個(gè)最相似數(shù)
據(jù)中出現(xiàn)次數(shù)最多的分類,作為新數(shù)據(jù)的分類。
距離度量常見有:歐氏距離(最常用)、曼哈頓距離、夾角余弦。

1.2 算法步驟

? 計(jì)算已知類別數(shù)據(jù)集中的點(diǎn)與當(dāng)前點(diǎn)之間的距離;
? 按照距離遞增次序排序;
? 選取與當(dāng)前點(diǎn)距離最小的k個(gè)點(diǎn);
? 確定前k個(gè)點(diǎn)所在類別的出現(xiàn)頻率;
? 返回前k個(gè)點(diǎn)所出現(xiàn)頻率最高的類別作為當(dāng)前點(diǎn)的預(yù)測分類。

案例一.k-近鄰算法代碼實(shí)現(xiàn)電影分類

創(chuàng)建數(shù)據(jù)集和標(biāo)簽,測試集;

dataset=np.array([[1,101],[5,89],[108,5],[115,8]])#四組二維特征
labels = ['愛情片','愛情片','動(dòng)作片','動(dòng)作片']

test_data = [101,20]#測試集

定義計(jì)算過程

import numpy as np
import collections

def classify(inx_test,dataset,labels,k):
    dist = np.sum((inx_test-dataset)**2,axis=1)**0.5 #計(jì)算距離
    k_labels = [labels[index] for index in dist.argsort()[0:k]] # 距離從小到大排列,取k個(gè)索引對應(yīng)k的個(gè)最近的標(biāo)簽
    label = collections.Counter(k_labels).most_common(1)[0][0]
    return label

輸入數(shù)據(jù)集,獲取測試集標(biāo)簽

#kNN分類
test_class0 = classify(test_data, dataset, labels, 3)
print(test_class0)
案例二.約會網(wǎng)站配對效果判定
2.1 案例背景

? 海倫女士一直使用在線約會網(wǎng)站尋找適合自己的約會對象。盡管約
會網(wǎng)站會推薦不同的人選,但她并不是喜歡每一個(gè)人。經(jīng)過一番總
結(jié),她發(fā)現(xiàn)自己交往過的人可以進(jìn)行如下分類:
? 不喜歡的人
? 魅力一般的人
? 極具魅力的人

? 海倫收集約會數(shù)據(jù)已經(jīng)有了一段時(shí)間,她把這些數(shù)據(jù)存放在文本文
件datingTestSet.txt中,每個(gè)樣本數(shù)據(jù)占據(jù)一行,總共有1000行。

海倫收集的樣本數(shù)據(jù)主要包含以下3種特征:
? 每年獲得的飛行常客里程數(shù)
? 玩視頻游戲所消耗時(shí)間百分比
? 每周消費(fèi)的冰淇淋公升數(shù)

2.1 數(shù)據(jù)預(yù)覽

數(shù)據(jù)讀取

import numpy as np
import pandas as pd

data = pd.read_csv('data\datingTestSet.txt',sep='   ',names=['x1','x2','x3','y'])
datingDataMat = data.loc[:,'x1':'x3']
datingLabels=data.loc[:,'y']

標(biāo)簽只有三種:{'didntLike', 'largeDoses', 'smallDoses'}
但三種特征值的量級不在一個(gè)級別,需要對三組特征值做數(shù)據(jù)歸一化處理。


image.png

數(shù)據(jù)歸一化處理。


image.png

上一個(gè)案例封裝的類,這里可以調(diào)用。
#計(jì)算錯(cuò)誤率
errorCount = 0.0

#前100作為測試,后900個(gè)作為訓(xùn)練
for i in range(100):
    classifierResult = classify(df_norm.values[i,:], df_norm.values[100:1001,:],list(datingLabels[100:1001]), 4)
    print("預(yù)測結(jié)果:%s\t真實(shí)類別:%s" % (classifierResult, datingLabels[i]))
    if classifierResult is not datingLabels[i]:
        errorCount += 1.0
print('錯(cuò)誤率:%f%%'%(errorCount/float(100)*100))
image.png
案例三.sklearn中的knn-鳶尾花分類
3.1 數(shù)據(jù)下載
import numpy as np
from sklearn import datasets
iris = datasets.load_iris()
##劃分?jǐn)?shù)據(jù)集特征、標(biāo)簽
iris_X = iris.data
iris_y = iris.target

使用scikit-learn處理劃分?jǐn)?shù)據(jù)集,并送入模型

from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
##劃分?jǐn)?shù)據(jù)集
iris_train_X,iris_test_X,iris_train_y,iris_test_y = train_test_split(iris_X,iris_y,test_size=0.2,random_state=0)

knn = KNeighborsClassifier(n_neighbors=6)
knn.fit(iris_train_X,iris_train_y)
predict_result = knn.predict(iris_test_X)
print('結(jié)果預(yù)測為',predict_result)
##計(jì)算準(zhǔn)確率
acc_rate = knn.score(iris_test_X,iris_test_y)
print('預(yù)測準(zhǔn)確率為',acc_rate)
3.2 結(jié)果
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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