演算法實踐:KNN分類(day08)

hutugui2009發表於2020-12-22

2.4 演算法實戰

2.4.1 Demo資料集–kNN分類

Step1: 庫函式匯入

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn.neighbors import KNeighborsClassifier
from sklearn import datasets

Step2: 資料匯入

# 使用鶯尾花資料集的前兩維資料,便於資料視覺化
iris = datasets.load_iris()
X = iris.data[:, :2]
y = iris.target

Step3: 模型訓練&視覺化

k_list = [1, 3, 5, 8, 10, 15]
h = .02
# 建立不同顏色的畫布
cmap_light = ListedColormap(['orange', 'cyan', 'cornflowerblue'])
cmap_bold = ListedColormap(['darkorange', 'c', 'darkblue'])

plt.figure(figsize=(15,14))
# 根據不同的k值進行視覺化
for ind,k in enumerate(k_list):
    clf = KNeighborsClassifier(k)
    clf.fit(X, y)
    # 畫出決策邊界
    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.subplot(321+ind)  
    plt.pcolormesh(xx, yy, Z, cmap=cmap_light)
    # 資料點視覺化到畫布
    plt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold,
                edgecolor='k', s=20)
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.title("3-Class classification (k = %i)"% k)

plt.show()

在這裡插入圖片描述

Step4: 原理簡析

如果選擇較小的K值,就相當於用較小的領域中的訓練例項進行預測,例如當k=1的時候,在分界點位置的資料很容易受到區域性的影響,圖中藍色的部分中還有部分綠色塊,主要是資料太區域性敏感。當k=15的時候,不同的資料基本根據顏色分開,當時進行預測的時候,會直接落到對應的區域,模型相對更加魯棒。

2.4.2 鶯尾花資料集–kNN分類

Step1: 庫函式匯入

import numpy as np
# 載入鶯尾花資料集
from sklearn import datasets
# 匯入KNN分類器
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split

Step2: 資料匯入&分析

# 匯入鶯尾花資料集
iris = datasets.load_iris()

X = iris.data
y = iris.target
# 得到訓練集合和驗證集合, 8: 2
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

Step3: 模型訓練

這裡我們設定引數k(n_neighbors)=5, 使用歐式距離(metric=minkowski & p=2)

# 訓練模型
clf = KNeighborsClassifier(n_neighbors=5, p=2, metric="minkowski")
clf.fit(X_train, y_train)
KNeighborsClassifier()

Step4:模型預測&視覺化

# 預測
X_pred = clf.predict(X_test)
acc = sum(X_pred == y_test) / X_pred.shape[0]
print("預測的準確率ACC: %.3f" % acc)
預測的準確率ACC: 0.967

我們用表格來看一下KNN的訓練和預測過程。這裡用表格進行視覺化:

  1. 訓練資料[表格對應list]
feat_1feat_2feat_3feat_4label
5.13.51.40.20
4.93.1.40.20
4.73.21.30.20
4.63.11.50.20
6.43.24.51.51
6.93.14.91.51
5.52.34.1.31
6.52.84.61.51
5.82.75.11.92
7.13.5.92.12
6.32.95.61.82
6.53.5.82.22
  1. knn.fit(X, y)的過程可以簡單認為是表格儲存
feat_1feat_2feat_3feat_4label
5.13.51.40.20
4.93.1.40.20
4.73.21.30.20
4.63.11.50.20
6.43.24.51.51
6.93.14.91.51
5.52.34.1.31
6.52.84.61.51
5.82.75.11.92
7.13.5.92.12
6.32.95.61.82
6.53.5.82.22
  1. knn.predict(x)預測過程會計算x和所有訓練資料的距離
    這裡我們使用歐式距離進行計算, 預測過程如下

x = [ 5. , 3.6 , 1.4 , 0.2 ] y = 0 x = [5. , 3.6, 1.4, 0.2] \\ y=0 x=[5.,3.6,1.4,0.2]y=0

step1: 計算x和所有訓練資料的距離

feat_1feat_2feat_3feat_4距離label
5.13.51.40.20.141421360
4.93.1.40.20.608276250
4.73.21.30.20.509901950
4.63.11.50.20.648074070
6.43.24.51.53.663331821
6.93.14.91.54.219004621
5.52.34.1.33.148015251
6.52.84.61.53.849675311
5.82.75.11.94.246174752
7.13.5.92.15.350700892
6.32.95.61.84.730750472
6.53.5.82.25.096076922

step2: 根據距離進行編號排序

距離升序編號feat_1feat_2feat_3feat_4距離label
15.13.51.40.20.141421360
34.93.1.40.20.608276250
24.73.21.30.20.509901950
44.63.11.50.20.648074070
66.43.24.51.53.663331821
86.93.14.91.54.219004621
55.52.34.1.33.148015251
76.52.84.61.53.849675311
95.82.75.11.94.246174752
127.13.5.92.15.350700892
106.32.95.61.84.730750472
116.53.5.82.25.096076922

step3: 我們設定k=5,選擇距離最近的k個樣本進行投票

距離升序編號feat_1feat_2feat_3feat_4距離label
15.13.51.40.20.141421360
34.93.1.40.20.608276250
24.73.21.30.20.509901950
44.63.11.50.20.648074070
66.43.24.51.53.663331821
86.93.14.91.54.219004621
55.52.34.1.33.148015251
76.52.84.61.53.849675311
95.82.75.11.94.246174752
127.13.5.92.15.350700892
106.32.95.61.84.730750472
116.53.5.82.25.096076922

step4: k近鄰的label進行投票

nn_labels = [0, 0, 0, 0, 1] --> 得到最後的結果0。


相關文章