深入浅出KNN算法(二) sklearn KNN实践
上次介紹了KNN的基本原理,以及KNN的幾個(gè)竅門,這次就來(lái)用sklearn實(shí)踐一下KNN算法。
一.Skelarn KNN參數(shù)概述
要使用sklearnKNN算法進(jìn)行分類,我們需要先了解sklearnKNN算法的一些基本參數(shù),那么這節(jié)就先介紹這些內(nèi)容吧。
def KNeighborsClassifier(n_neighbors = 5,weights = 'uniform',algorithm = '',leaf_size = '30',p = 2,metric = 'minkowski',metric_params = None,n_jobs = None)- n_neighbors: 這個(gè)值就是指KNN中的"K"了,前面說(shuō)到過(guò),調(diào)整K值,算法會(huì)有不同的效果。 - weights(權(quán)重):最普遍的 KNN 算法無(wú)論距離如何,權(quán)重都一樣,但有時(shí)候我們想搞點(diǎn)特殊化,比如距離更近的點(diǎn)讓它更加重要。這時(shí)候就需要 weight 這個(gè)參數(shù)了,這個(gè)參數(shù)有三個(gè)可選參數(shù)的值, 決定了如何分配權(quán)重。參數(shù)選項(xiàng)如下:? 'uniform':不管遠(yuǎn)近權(quán)重都一樣,就是最普通的 KNN 算法的形式。? 'distance':權(quán)重和距離成反比,距離預(yù)測(cè)目標(biāo)越近具有越高的權(quán)重。? 自定義函數(shù):自定義一個(gè)函數(shù),根據(jù)輸入的坐標(biāo)值返回對(duì)應(yīng)的權(quán)重,達(dá)到自定義權(quán)重的目的。 - algorithm:在 sklearn 中,要構(gòu)建 KNN 模型有三種構(gòu)建方式,1. 暴力法,就是直接計(jì)算距離存儲(chǔ)比較的那種放松。2. 使用 kd 樹(shù)構(gòu)建 KNN 模型 3. 使用球樹(shù)構(gòu)建。 其中暴力法適合數(shù)據(jù)較小的方式,否則效率會(huì)比較低。如果數(shù)據(jù)量比較大一般會(huì)選擇用 KD 樹(shù)構(gòu)建 KNN 模型,而當(dāng) KD 樹(shù)也比較慢的時(shí)候,則可以試試球樹(shù)來(lái)構(gòu)建 KNN。參數(shù)選項(xiàng)如下:? 'brute' :蠻力實(shí)現(xiàn)? 'kd_tree':KD 樹(shù)實(shí)現(xiàn) KNN? 'ball_tree':球樹(shù)實(shí)現(xiàn) KNN ? 'auto': 默認(rèn)參數(shù),自動(dòng)選擇合適的方法構(gòu)建模型不過(guò)當(dāng)數(shù)據(jù)較小或比較稀疏時(shí),無(wú)論選擇哪個(gè)最后都會(huì)使用 'brute' - leaf_size:如果是選擇蠻力實(shí)現(xiàn),那么這個(gè)值是可以忽略的,當(dāng)使用KD樹(shù)或球樹(shù), 它就是是停止建子樹(shù)的葉子節(jié)點(diǎn)數(shù)量的閾值。默認(rèn)30,但如果數(shù)據(jù)量增多這個(gè)參數(shù)需要增大, 否則速度過(guò)慢不說(shuō),還容易過(guò)擬合。 - p:和metric結(jié)合使用的,當(dāng)metric參數(shù)是"minkowski"的時(shí)候,p=1為曼哈頓距離,p=2為歐式距離。默認(rèn)為p=2。 - metric:指定距離度量方法,一般都是使用歐式距離。? 'euclidean' :歐式距離? 'manhattan':曼哈頓距離? 'chebyshev':切比雪夫距離? 'minkowski': 閔可夫斯基距離,默認(rèn)參數(shù) - n_jobs:指定多少個(gè)CPU進(jìn)行運(yùn)算,默認(rèn)是-1,也就是全部都算。二. KNN代碼實(shí)例
KNN算法算是機(jī)器學(xué)習(xí)里面最簡(jiǎn)單的算法之一了,我們來(lái)sklearn官方給出的例子,來(lái)看看KNN應(yīng)該怎樣使用吧:
數(shù)據(jù)集使用的是著名的鳶尾花數(shù)據(jù)集,用KNN來(lái)對(duì)它做分類。我們先看看鳶尾花長(zhǎng)的啥樣。
上面這個(gè)就是鳶尾花了,這個(gè)鳶尾花數(shù)據(jù)集主要包含了鳶尾花的花萼長(zhǎng)度,花萼寬度,花瓣長(zhǎng)度,花瓣寬度4個(gè)屬性(特征),以及鳶尾花卉屬于『Setosa,Versicolour,Virginica』三個(gè)種類中的哪一類(這三種都長(zhǎng)什么樣我也不知道)。
在使用KNN算法之前,我們要先決定K的值是多少,要選出最優(yōu)的K值,可以使用sklearn中的交叉驗(yàn)證方法,代碼如下:
from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score import matplotlib.pyplot as plt from sklearn.neighbors import KNeighborsClassifier#讀取鳶尾花數(shù)據(jù)集 iris = load_iris() x = iris.data y = iris.target k_range = range(1, 31) k_error = []#循環(huán),取k=1到k=31,查看誤差效果 for k in k_range:knn = KNeighborsClassifier(n_neighbors=k)# cv參數(shù)決定數(shù)據(jù)集劃分比例,這里是按照5:1劃分訓(xùn)練集和測(cè)試集scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy')k_error.append(1 - scores.mean())#畫(huà)圖,x軸為k值,y值為誤差值 plt.plot(k_range, k_error) plt.xlabel('Value of K for KNN') plt.ylabel('Error') plt.show()運(yùn)行后,我們可以得到下面這樣的圖:
有了這張圖,我們就能明顯看出K值取多少的時(shí)候誤差最小,這里明顯是K=11最好。當(dāng)然在實(shí)際問(wèn)題中,如果數(shù)據(jù)集比較大,那為減少訓(xùn)練時(shí)間,K的取值范圍可以縮小。
有了K值我們就能運(yùn)行KNN算法了,具體代碼如下:
import matplotlib.pyplot as plt from numpy import * from matplotlib.colors import ListedColormap from sklearn import neighbors, datasetsn_neighbors = 11#導(dǎo)入一些要玩的數(shù)據(jù) iris = datasets.load_iris() x = iris.data[:, :2] #我們只采用前兩個(gè)feature,方便畫(huà)圖在二維平面顯示 y = iris.targeth = .02 #網(wǎng)格中的步長(zhǎng)# 創(chuàng)建彩色的圖 cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF']) cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF'])#weights 是KNN模型中的一個(gè)參數(shù),上述參數(shù)介紹中有介紹,這里繪制兩種權(quán)重參數(shù)下KNN的效果圖 for weights in ['uniform', 'distance']:# 創(chuàng)建了一個(gè)knn分類器的實(shí)例,并擬合數(shù)據(jù)。clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights)clf.fit(x, y)# 繪制決策邊界。為此,我們將為每個(gè)分配一個(gè)顏色# 來(lái)繪制網(wǎng)格中的點(diǎn) [x_min, x_max]x[y_min, y_max].x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 1y_min, y_max = x[:, 1].min() - 1, x[:, 1].max() + 1xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])# 將結(jié)果放入一個(gè)彩色圖中Z = Z.reshape(xx.shape)plt.figure()plt.pcolormesh(xx, yy, Z, cmap=cmap_light)# 繪制訓(xùn)練點(diǎn)plt.scatter(x[:, 0], x[:, 1], c=y, cmap=cmap_bold)plt.xlim(xx.min(), xx.max())plt.ylim(yy.min(), yy.max())plt.title("3-Class classification (k = %i, weights = '%s')"% (n_neighbors, weights))plt.show()KNN和Kmeans
前面說(shuō)到過(guò),KNN和Kmeans聽(tīng)起來(lái)有些像,但本質(zhì)是有區(qū)別的,這里我們就順便說(shuō)一下兩者的異同吧。
相同:
相異:
Knn和Kmeans的核心都是通過(guò)計(jì)算空間中點(diǎn)的距離來(lái)實(shí)現(xiàn)目的,只是他們的目的是不同的。KNN的最終目的是分類,而Kmeans的目的是給所有距離相近的點(diǎn)分配一個(gè)類別,也就是聚類。
簡(jiǎn)單說(shuō),就是畫(huà)一個(gè)圈,KNN是讓進(jìn)來(lái)圈子里的人變成自己人,Kmeans是讓原本在圈內(nèi)的人歸成一類人。
總結(jié)
以上是生活随笔為你收集整理的深入浅出KNN算法(二) sklearn KNN实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python-css反爬之svg映射
- 下一篇: 一次旁站信息泄露的dedecms站点渗透