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 npnimport matplotlib.pyplot as pltnfrom matplotlib.colors import ListedColormapnfrom sklearn import neighbors, datasetsnimport pandas as pdn
(2)然後生成樣本數據,這裡要注意需要生成只有兩個特徵值的數據集。
from sklearn.datasets.samples_generator import make_classificationn# X為樣本特徵,y為樣本類別輸出, 共200個樣本,每個樣本2個特徵,輸出有3個類別,沒有冗餘特徵,每個類別一個簇nX, y = make_classification(n_samples=200, n_features=2, n_redundant=0,n n_clusters_per_class=1, n_classes=3)n#之所以生成2個特徵值是因為需要在二維平面上可視化展示預測結果,所以只能是2個,3個都不行nplt.scatter(X[:, 0], X[:, 1], marker=o, c=y)nplt.show() #根據隨機生成樣本不同,圖形也不同n
本次結果生成的三個類別分布如下:
(3)採用KNeighborsClassifier進行分類與預測
clf = neighbors.KNeighborsClassifier(n_neighbors = 15 , weights=distance)nclf.fit(X, y) #用KNN來擬合模型,我們選擇K=15,權重為距離遠近nh = .02 #網格中的步長n#確認訓練集的邊界n#生成隨機數據來做測試集,然後作預測nx_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1ny_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1nxx, yy = np.meshgrid(np.arange(x_min, x_max, h),n np.arange(y_min, y_max, h)) #生成網格型二維數據對nZ = clf.predict(np.c_[xx.ravel(), yy.ravel()])n
(4)畫出不同預測類別的區域地圖以及實際訓練數據的類別位置
# Create color mapsncmap_light = ListedColormap([#FFAAAA, #AAFFAA, #AAAAFF]) #給不同區域賦以顏色ncmap_bold = ListedColormap([#FF0000, #003300, #0000FF])#給不同屬性的點賦以顏色n#將預測的結果在平面坐標中畫出其類別區域nZ = Z.reshape(xx.shape)nplt.figure()nplt.pcolormesh(xx, yy, Z, cmap=cmap_light)n# 也畫出所有的訓練集數據nplt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold)nplt.xlim(xx.min(), xx.max())nplt.ylim(yy.min(), yy.max())nnplt.show()n
得到結果為:
結果可以看出,預測區域能夠涵蓋大部分的訓練數據,除了少部分訓練數據分布異常外(如部分紅色點進入綠色區域,藍色點進入紅色區域)。
3.分類器RadiusNeighborsClassifier的python實現以及結果的可視化
其步驟與2中KNeighborsClassifier步驟基本相同,主要是在擬合與預測上採用KNeighborsClassifier分類函數,整個代碼為:
clf1 = neighbors.RadiusNeighborsClassifier(10.0, weights=distance)nclf1.fit(X, y)nZ1 = clf1.predict(np.c_[xx.ravel(), yy.ravel()])nZ1 = Z1.reshape(xx.shape)nplt.figure()nplt.pcolormesh(xx, yy, Z1, cmap=cmap_light)n# 也畫出所有的訓練集數據nplt.scatter(X[:, 0], X[:, 1], c=y, cmap=cmap_bold)nplt.xlim(xx.min(), xx.max())nplt.ylim(yy.min(), yy.max())nnplt.show()n
得到結果:
此圖與上圖相比,還是有不同的,特別是綠色區域範圍擴大了。哪種方法比較好呢?從可視化圖形不容易看出,可視化只能直觀看出二者的結果差異性,最好的評價二者分類優劣的方法就是計算其預測的誤差率(loss funtion)或者準確率(預測正確的個數佔總數的比例)。
推薦閱讀:
※二、機器學習面試之有必要手推SVM嗎?
※Logistic回歸的檢驗方法有哪些?R中有比較完備的處理logit回歸的包嗎?
※論文篇:Latent Dirichlet Allocation(LDA)(二)
※【翻譯 - CS229】對於機器學習應用的建議
※【活動預告】近期更新的大數據、機器學習線上線下沙龍活動(12場)