天天看點

深入淺出KNN算法(二) sklearn KNN實踐一.Skelarn KNN參數概述二. KNN代碼執行個體

姊妹篇:

深入淺出KNN算法(一) 原理介紹

上次介紹了KNN的基本原理,以及KNN的幾個竅門,這次就來用sklearn實踐一下KNN算法。

一.Skelarn KNN參數概述

要使用sklearnKNN算法進行分類,我們需要先了解sklearnKNN算法的一些基本參數,那麼這節就先介紹這些内容吧。

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代碼執行個體

KNN算法算是機器學習裡面最簡單的算法之一了,我們來sklearn官方給出的例子,來看看KNN應該怎樣使用吧:

資料集使用的是著名的鸢尾花資料集,用KNN來對它做分類。我們先看看鸢尾花長的啥樣。

深入淺出KNN算法(二) sklearn KNN實踐一.Skelarn KNN參數概述二. KNN代碼執行個體

上面這個就是鸢尾花了,這個鸢尾花資料集主要包含了鸢尾花的花萼長度,花萼寬度,花瓣長度,花瓣寬度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()
           

運作後,我們可以得到下面這樣的圖:

深入淺出KNN算法(二) sklearn KNN實踐一.Skelarn KNN參數概述二. KNN代碼執行個體

有了這張圖,我們就能明顯看出K值取多少的時候誤差最小,這裡明顯是K=11最好。當然在實際問題中,如果資料集比較大,那為減少訓練時間,K的取值範圍可以縮小。

有了K值我們就能運作KNN算法了,具體代碼如下:

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

前面說到過,KNN和Kmeans聽起來有些像,但本質是有差別的,這裡我們就順便說一下兩者的異同吧。

相同:

  1. K值都是重點
  2. 都需要計算平面中點的距離

相異:

Knn和Kmeans的核心都是通過計算空間中點的距離來實作目的,隻是他們的目的是不同的。KNN的最終目的是分類,而Kmeans的目的是給所有距離相近的點配置設定一個類别,也就是聚類。

簡單說,就是畫一個圈,KNN是讓進來圈子裡的人變成自己人,Kmeans是讓原本在圈内的人歸成一類人。

以上

轉載于:https://www.cnblogs.com/listenfwind/p/10685192.html