姊妹篇:
深刻淺出KNN算法(一) 原理介紹html
上次介紹了KNN的基本原理,以及KNN的幾個竅門,此次就來用sklearn實踐一下KNN算法。算法
要使用sklearnKNN算法進行分類,咱們須要先了解sklearnKNN算法的一些基本參數,那麼這節就先介紹這些內容吧。app
def KNeighborsClassifier(n_neighbors = 5, weights='uniform', algorithm = '', leaf_size = '30', p = 2, metric = 'minkowski', metric_params = None, n_jobs = None ) - n_neighbors:這個值就是指 KNN 中的 「K」了。前面說到過,經過調整 K 值,算法會有不一樣的效果。 - weights(權重):最廣泛的 KNN 算法不管距離如何,權重都同樣,但有時候咱們想搞點特殊化,好比距離更近的點讓它更加劇要。這時候就須要 weight 這個參數了,這個參數有三個可選參數的值,決定了如何分配權重。參數選項以下: • 'uniform':無論遠近權重都同樣,就是最普通的 KNN 算法的形式。 • 'distance':權重和距離成反比,距離預測目標越近具備越高的權重。 • 自定義函數:自定義一個函數,根據輸入的座標值返回對應的權重,達到自定義權重的目的。 - algorithm:在 sklearn 中,要構建 KNN 模型有三種構建方式,1. 暴力法,就是直接計算距離存儲比較的那種放鬆。2. 使用 kd 樹構建 KNN 模型 3. 使用球樹構建。 其中暴力法適合數據較小的方式,不然效率會比較低。若是數據量比較大通常會選擇用 KD 樹構建 KNN 模型,而當 KD 樹也比較慢的時候,則能夠試試球樹來構建 KNN。參數選項以下: • 'brute' :蠻力實現 • 'kd_tree':KD 樹實現 KNN • 'ball_tree':球樹實現 KNN • 'auto': 默認參數,自動選擇合適的方法構建模型 不過當數據較小或比較稀疏時,不管選擇哪一個最後都會使用 'brute' - leaf_size:若是是選擇蠻力實現,那麼這個值是能夠忽略的,當使用KD樹或球樹,它就是是中止建子樹的葉子節點數量的閾值。默認30,但若是數據量增多這個參數須要增大,不然速度過慢不說,還容易過擬合。 - p:和metric結合使用的,當metric參數是"minkowski"的時候,p=1爲曼哈頓距離, p=2爲歐式距離。默認爲p=2。 - metric:指定距離度量方法,通常都是使用歐式距離。 • 'euclidean' :歐式距離 • 'manhattan':曼哈頓距離 • 'chebyshev':切比雪夫距離 • 'minkowski': 閔可夫斯基距離,默認參數 - n_jobs:指定多少個CPU進行運算,默認是-1,也就是所有都算。
KNN算法算是機器學習裏面最簡單的算法之一了,咱們來sklearn官方給出的例子,來看看KNN應該怎樣使用吧:機器學習
數據集使用的是著名的鳶尾花數據集,用KNN來對它作分類。咱們先看看鳶尾花長的啥樣。ide
上面這個就是鳶尾花了,這個鳶尾花數據集主要包含了鳶尾花的花萼長度,花萼寬度,花瓣長度,花瓣寬度4個屬性(特徵),以及鳶尾花卉屬於『Setosa,Versicolour,Virginica』三個種類中的哪一類(這三種都長什麼樣我也不知道)。函數
在使用KNN算法以前,咱們要先決定K的值是多少,要選出最優的K值,可使用sklearn中的交叉驗證方法,代碼以下:學習
from sklearn.datasets import load_iris from sklearn.model_selection import cross_val_score import matplotlib.pyplot as plt from sklearn.neighbors import KNeighborsClassifier #讀取鳶尾花數據集 iris = load_iris() x = iris.data y = iris.target k_range = range(1, 31) k_error = [] #循環,取k=1到k=31,查看偏差效果 for k in k_range: knn = KNeighborsClassifier(n_neighbors=k) #cv參數決定數據集劃分比例,這裏是按照5:1劃分訓練集和測試集 scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy') k_error.append(1 - scores.mean()) #畫圖,x軸爲k值,y值爲偏差值 plt.plot(k_range, k_error) plt.xlabel('Value of K for KNN') plt.ylabel('Error') plt.show()
運行後,咱們能夠獲得下面這樣的圖:
有了這張圖,咱們就能明顯看出K值取多少的時候偏差最小,這裏明顯是K=11最好。固然在實際問題中,若是數據集比較大,那爲減小訓練時間,K的取值範圍能夠縮小。測試
有了K值咱們就能運行KNN算法了,具體代碼以下:idea
import matplotlib.pyplot as plt from numpy import * from matplotlib.colors import ListedColormap from sklearn import neighbors, datasets n_neighbors = 11 # 導入一些要玩的數據 iris = datasets.load_iris() x = iris.data[:, :2] # 咱們只採用前兩個feature,方便畫圖在二維平面顯示 y = iris.target h = .02 # 網格中的步長 # 建立彩色的圖 cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF']) cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF']) #weights是KNN模型中的一個參數,上述參數介紹中有介紹,這裏繪製兩種權重參數下KNN的效果圖 for weights in ['uniform', 'distance']: # 建立了一個knn分類器的實例,並擬合數據。 clf = neighbors.KNeighborsClassifier(n_neighbors, weights=weights) clf.fit(x, y) # 繪製決策邊界。爲此,咱們將爲每一個分配一個顏色 # 來繪製網格中的點 [x_min, x_max]x[y_min, y_max]. x_min, x_max = x[:, 0].min() - 1, x[:, 0].max() + 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)) Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # 將結果放入一個彩色圖中 Z = Z.reshape(xx.shape) plt.figure() plt.pcolormesh(xx, yy, Z, cmap=cmap_light) # 繪製訓練點 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聽起來有些像,但本質是有區別的,這裏咱們就順便說一下二者的異同吧。code
相同:
相異:
Knn和Kmeans的核心都是經過計算空間中點的距離來實現目的,只是他們的目的是不一樣的。KNN的最終目的是分類,而Kmeans的目的是給全部距離相近的點分配一個類別,也就是聚類。
簡單說,就是畫一個圈,KNN是讓進來圈子裏的人變成本身人,Kmeans是讓本來在圈內的人歸成一類人。
以上