1. 程式人生 > 其它 >KNN兩種分類器的python簡單實現及其結果視覺化比較

KNN兩種分類器的python簡單實現及其結果視覺化比較

1.KNN演算法簡介及其兩種分類器

KNN,即K近鄰法(k-nearst neighbors),所謂的k最近鄰,就是指最接近的k個鄰居(資料),即每個樣本都可以由它的K個鄰居來表達。kNN演算法的核心思想是,在一個含未知樣本的空間,可以根據離這個樣本最鄰近的k個樣本的資料型別來確定樣本的資料型別。 在scikit-learn 中,與近鄰法這一大類相關的類庫都在sklearn.neighbors包之中。其中分類器有KNN分類樹KNeighborsClassifier、限定半徑最近鄰分類樹的類RadiusNeighborsClassifier以及最近質心分類演算法NearestCentroid等等。前兩種分類演算法中,scikit-learn實現兩個不同的最近鄰分類器:KNeighborsClassifier基於每個查詢點的k個最近鄰點實現學習,其中k是使用者指定的最近鄰數量。 RadiusNeighborsClassifier基於每個訓練點的固定半徑r內的最近鄰搜尋實現學習,其中r是使用者指定的半徑浮點值。關於這兩種分類器的差別可以參考KNN演算法的KD樹和球樹進行了解。

2.分類器KNeighborsClassifier的python實現以及結果的視覺化

基於scikit-learn的KNeighborsClassifier以及RadiusNeighborsClassifier分類器,本文構建樣本資料,採用這兩種方法進行分類預測,根據結果畫出二者的預測集,從而進行比較。 (1)首先是匯入各種庫。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import neighbors, datasets
import pandas as pd

(2)然後生成樣本資料,這裡要注意需要生成只有兩個特徵值的資料集。

from sklearn.datasets.samples_generator 
import make_classification
# X為樣本特徵,y為樣本類別輸出, 共200個樣本,每個樣本2個特徵,輸出有3個類別,沒有冗餘特徵,每個類別一個簇
X, y = make_classification(n_samples=200, n_features=2, n_redundant=0,n_clusters_per_class=1, n_classes=3)
#之所以生成2個特徵值是因為需要在二維平面上視覺化展示預測結果,所以只能是2個,3個都不行
plt.scatter(X[:, 0], X[:, 1], marker='o', c=y)
plt.show() #根據隨機生成樣本不同,圖形也不同

本次結果生成的三個類別分佈如下:

(3)採用KNeighborsClassifier進行分類與預測

clf = neighbors.KNeighborsClassifier(n_neighbors = 15 , weights='distance')clf.fit(X, y)  
#用KNN來擬合模型,我們選擇K=15,權重為距離遠近h = .02  
#網格中的步長#確認訓練集的邊界
#生成隨機資料來做測試集,然後作預測
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()])

(4)畫出不同預測類別的區域地圖以及實際訓練資料的類別位置

# Create color mapscmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF']) #給不同區域賦以顏色cmap_bold = ListedColormap(['#FF0000', '#003300', '#0000FF'])#給不同屬性的點賦以顏色#將預測的結果在平面座標中畫出其類別區域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.show()

得到結果為:

結果可以看出,預測區域能夠涵蓋大部分的訓練資料,除了少部分訓練資料分佈異常外(如部分紅色點進入綠色區域,藍色點進入紅色區域)。

3.分類器RadiusNeighborsClassifier的python實現以及結果的視覺化

其步驟與2中KNeighborsClassifier步驟基本相同,主要是在擬合與預測上採用KNeighborsClassifier分類函式,整個程式碼為:

clf1 = neighbors.RadiusNeighborsClassifier(10.0, weights='distance')
clf1.fit(X, y)Z1 = clf1.predict(np.c_[xx.ravel(), yy.ravel()])
Z1 = Z1.reshape(xx.shape)plt.figure()
plt.pcolormesh(xx, yy, Z1, 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.show()

得到結果:

此圖與上圖相比,還是有不同的,特別是綠色區域範圍擴大了。哪種方法比較好呢?從視覺化圖形不容易看出,視覺化只能直觀看出二者的結果差異性,最好的評價二者分類優劣的方法就是計算其預測的誤差率(loss funtion)或者準確率(預測正確的個數佔總數的比例)。