python機(jī)器學(xué)習(xí)之KNN分類算法
本文為大家分享了python機(jī)器學(xué)習(xí)之KNN分類算法,供大家參考,具體內(nèi)容如下
1、KNN分類算法
KNN分類算法(K-Nearest-Neighbors Classification),又叫K近鄰算法,是一個(gè)概念極其簡(jiǎn)單,而分類效果又很優(yōu)秀的分類算法。
他的核心思想就是,要確定測(cè)試樣本屬于哪一類,就尋找所有訓(xùn)練樣本中與該測(cè)試樣本“距離”最近的前K個(gè)樣本,然后看這K個(gè)樣本大部分屬于哪一類,那么就認(rèn)為這個(gè)測(cè)試樣本也屬于哪一類。簡(jiǎn)單的說(shuō)就是讓最相似的K個(gè)樣本來(lái)投票決定。
這里所說(shuō)的距離,一般最常用的就是多維空間的歐式距離。這里的維度指特征維度,即樣本有幾個(gè)特征就屬于幾維。
KNN示意圖如下所示。(圖片來(lái)源:百度百科)
上圖中要確定測(cè)試樣本綠色屬于藍(lán)色還是紅色。
顯然,當(dāng)K=3時(shí),將以1:2的投票結(jié)果分類于紅色;而K=5時(shí),將以3:2的投票結(jié)果分類于藍(lán)色。
KNN算法簡(jiǎn)單有效,但沒(méi)有優(yōu)化的暴力法效率容易達(dá)到瓶頸。如樣本個(gè)數(shù)為N,特征維度為D的時(shí)候,該算法時(shí)間復(fù)雜度呈O(DN)增長(zhǎng)。
所以通常KNN的實(shí)現(xiàn)會(huì)把訓(xùn)練數(shù)據(jù)構(gòu)建成K-D Tree(K-dimensional tree),構(gòu)建過(guò)程很快,甚至不用計(jì)算D維歐氏距離,而搜索速度高達(dá)O(D*log(N))。
不過(guò)當(dāng)D維度過(guò)高,會(huì)產(chǎn)生所謂的”維度災(zāi)難“,最終效率會(huì)降低到與暴力法一樣。
因此通常D>20以后,最好使用更高效率的Ball-Tree,其時(shí)間復(fù)雜度為O(D*log(N))。
人們經(jīng)過(guò)長(zhǎng)期的實(shí)踐發(fā)現(xiàn)KNN算法雖然簡(jiǎn)單,但能處理大規(guī)模的數(shù)據(jù)分類,尤其適用于樣本分類邊界不規(guī)則的情況。最重要的是該算法是很多高級(jí)機(jī)器學(xué)習(xí)算法的基礎(chǔ)。
當(dāng)然,KNN算法也存在一切問(wèn)題。比如如果訓(xùn)練數(shù)據(jù)大部分都屬于某一類,投票算法就有很大問(wèn)題了。這時(shí)候就需要考慮設(shè)計(jì)每個(gè)投票者票的權(quán)重了。
2、測(cè)試數(shù)據(jù)
測(cè)試數(shù)據(jù)的格式仍然和前面使用的身高體重?cái)?shù)據(jù)一致。不過(guò)數(shù)據(jù)增加了一些:
1.5 40 thin
1.5 50 fat
1.5 60 fat
1.6 40 thin
1.6 50 thin
1.6 60 fat
1.6 70 fat
1.7 50 thin
1.7 60 thin
1.7 70 fat
1.7 80 fat
1.8 60 thin
1.8 70 thin
1.8 80 fat
1.8 90 fat
1.9 80 thin
1.9 90 fat
3、Python代碼
scikit-learn提供了優(yōu)秀的KNN算法支持。使用Python代碼如下:
# -*- coding: utf-8 -*- import numpy as np from sklearn import neighbors from sklearn.metrics import precision_recall_curve from sklearn.metrics import classification_report from sklearn.cross_validation import train_test_split import matplotlib.pyplot as plt ''' 數(shù)據(jù)讀入 ''' data = [] labels = [] with open("data\\1.txt") as ifile: for line in ifile: tokens = line.strip().split(' ') data.append([float(tk) for tk in tokens[:-1]]) labels.append(tokens[-1]) x = np.array(data) labels = np.array(labels) y = np.zeros(labels.shape) ''' 標(biāo)簽轉(zhuǎn)換為0/1 ''' y[labels=='fat']=1 ''' 拆分訓(xùn)練數(shù)據(jù)與測(cè)試數(shù)據(jù) ''' x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2) ''' 創(chuàng)建網(wǎng)格以方便繪制 ''' h = .01 x_min, x_max = x[:, 0].min() - 0.1, x[:, 0].max() + 0.1 y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1 xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h)) ''' 訓(xùn)練KNN分類器 ''' clf = neighbors.KNeighborsClassifier(algorithm='kd_tree') clf.fit(x_train, y_train) '''測(cè)試結(jié)果的打印''' answer = clf.predict(x) print(x) print(answer) print(y) print(np.mean( answer == y)) '''準(zhǔn)確率與召回率''' precision, recall, thresholds = precision_recall_curve(y_train, clf.predict(x_train)) answer = clf.predict_proba(x)[:,1] print(classification_report(y, answer, target_names = ['thin', 'fat'])) ''' 將整個(gè)測(cè)試空間的分類結(jié)果用不同顏色區(qū)分開(kāi)''' answer = clf.predict_proba(np.c_[xx.ravel(), yy.ravel()])[:,1] z = answer.reshape(xx.shape) plt.contourf(xx, yy, z, cmap=plt.cm.Paired, alpha=0.8) ''' 繪制訓(xùn)練樣本 ''' plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, cmap=plt.cm.Paired) plt.xlabel(u'身高') plt.ylabel(u'體重') plt.show()
4、結(jié)果分析
其輸出結(jié)果如下:
[ 0. 0. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 1.]
[ 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 0. 1. 1. 0. 1.]
準(zhǔn)確率=0.94, score=0.94
precision recall f1-score support
thin 0.89 1.00 0.94 8
fat 1.00 0.89 0.94 9
avg / total 0.95 0.94 0.94 17
KNN分類器在眾多分類算法中屬于最簡(jiǎn)單的之一,需要注意的地方不多。有這幾點(diǎn)要說(shuō)明:
1、KNeighborsClassifier可以設(shè)置3種算法:‘brute',‘kd_tree',‘ball_tree'。如果不知道用哪個(gè)好,設(shè)置‘a(chǎn)uto'讓KNeighborsClassifier自己根據(jù)輸入去決定。
2、注意統(tǒng)計(jì)準(zhǔn)確率時(shí),分類器的score返回的是計(jì)算正確的比例,而不是R2。R2一般應(yīng)用于回歸問(wèn)題。
3、本例先根據(jù)樣本中身高體重的最大最小值,生成了一個(gè)密集網(wǎng)格(步長(zhǎng)h=0.01),然后將網(wǎng)格中的每一個(gè)點(diǎn)都當(dāng)成測(cè)試樣本去測(cè)試,最后使用contourf函數(shù),使用不同的顏色標(biāo)注出了胖、廋兩類。
容易看到,本例的分類邊界,屬于相對(duì)復(fù)雜,但卻又與距離呈現(xiàn)明顯規(guī)則的鋸齒形。
這種邊界線性函數(shù)是難以處理的。而KNN算法處理此類邊界問(wèn)題具有天生的優(yōu)勢(shì)。我們?cè)诤罄m(xù)的系列中會(huì)看到,這個(gè)數(shù)據(jù)集達(dá)到準(zhǔn)確率=0.94算是很優(yōu)秀的結(jié)果了。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python實(shí)現(xiàn)簡(jiǎn)易聊天室(Linux終端)
這篇文章主要為大家詳細(xì)介紹了Linux終端上python實(shí)現(xiàn)簡(jiǎn)易聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07python 監(jiān)測(cè)內(nèi)存和cpu的使用率實(shí)例
今天小編就為大家分享一篇python 監(jiān)測(cè)內(nèi)存和cpu的使用率實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-11-11Python監(jiān)聽(tīng)剪切板實(shí)現(xiàn)方法代碼實(shí)例
這篇文章主要介紹了Python監(jiān)聽(tīng)剪切板實(shí)現(xiàn)方法代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11Keras使用預(yù)訓(xùn)練模型遷移學(xué)習(xí)單通道灰度圖像詳解
這篇文章主要介紹了Keras使用預(yù)訓(xùn)練模型遷移學(xué)習(xí)單通道灰度圖像詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-02-02