【火爐煉AI】機器學習030-KNN分類器模型的構建
(本文所使用的Python庫和版本號: Python 3.6, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )
KNN(K-nearest neighbors)是用K個最近鄰的訓練資料集來尋找未知物件分類的一種演算法。其基本的核心思想在我的上一篇文章中介紹過了。
1. 準備資料集
此處我的資料集準備包括資料載入和資料視覺化,這部分比較簡單,以前文章中使用了多次,直接看資料分佈圖。

2. 構建KNN分類器模型
2.1 KNN分類器模型的構建和訓練
構建KNN分類器模型的方法和SVM,RandomForest的方法類似,程式碼如下:
# 構建KNN分類模型 from sklearn.neighbors import KNeighborsClassifier K=10 # 暫定10個最近樣本 KNN=KNeighborsClassifier(K,weights='distance') KNN.fit(dataset_X,dataset_y) # 使用該資料集訓練模型 複製程式碼
上面使用資料集訓練了這個KNN模型,但是我們怎麼知道該模型的訓練效果了?下面繪製了分類模型在訓練資料集上的分類效果,從邊界上來看,該分類器比較清晰的將這個資料集區分開來。

2.1 用訓練好的KNN分類器預測新樣本
直接上程式碼:
# 用訓練好的KNN模型預測新樣本 new_sample=np.array([[4.5,3.6]]) predicted=KNN.predict(new_sample)[0] print("KNN predicted:{}".format(predicted)) 複製程式碼
得到的結果是2,表示該新樣本屬於第2類。
下面我們將這個新樣本繪製到圖中,看看它在圖中的位置。
為了繪製新樣本和其周圍的K個樣本的位置,我修改了上面的plot_classifier函式,如下為程式碼:
# 為了檢視新樣本在原資料集中的位置,也為了檢視新樣本週圍最近的K個樣本位置, # 我修改了上面的plot_classifier函式,如下所示: def plot_classifier2(KNN_classifier, X, y,new_sample,K): x_min, x_max = min(X[:, 0]) - 1.0, max(X[:, 0]) + 1.0 # 計算圖中座標的範圍 y_min, y_max = min(X[:, 1]) - 1.0, max(X[:, 1]) + 1.0 step_size = 0.01 # 設定step size x_values, y_values = np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step_size)) # 構建網格資料 mesh_output = KNN_classifier.predict(np.c_[x_values.ravel(), y_values.ravel()]) mesh_output = mesh_output.reshape(x_values.shape) plt.figure() plt.pcolormesh(x_values, y_values, mesh_output, cmap=plt.cm.gray) plt.scatter(X[:, 0], X[:, 1], c=y, s=80, edgecolors='black', linewidth=1, cmap=plt.cm.Paired) # 繪製新樣本所在的位置 plt.scatter(new_sample[:,0],new_sample[:,1],marker='*',color='red') # 繪製新樣本週圍最近的K個樣本,只適用於KNN # Extract k nearest neighbors dist, indices = KNN_classifier.kneighbors(new_sample) plt.scatter(dataset_X[indices][0][:][:,0],dataset_X[indices][0][:][:,1], marker='x',s=80,color='r') # specify the boundaries of the figure plt.xlim(x_values.min(), x_values.max()) plt.ylim(y_values.min(), y_values.max()) # specify the ticks on the X and Y axes plt.xticks((np.arange(int(min(X[:, 0])), int(max(X[:, 0])), 1.0))) plt.yticks((np.arange(int(min(X[:, 1])), int(max(X[:, 1])), 1.0))) plt.show() 複製程式碼
直接代入執行後得到結果圖:

從圖中可以看出,紅色的五角星是我們的新樣本,而紅色的叉號表示與其最近的K個鄰居。可以看出,這些鄰居中的大多數都位於第二個類別中,故而新樣本也被劃分到第二個類比,通過predict得到的結果也是2。
########################小**********結###############################
1,構建和訓練KNN分類器非常簡單,只需要用sklearn匯入KNNClassifier,然後用fit()函式即可。
2,KNN分類器儲存了所有可用的訓練集資料點,在新的資料點需要預測時,首先計算該新資料點和內部儲存的所有資料點的相似度(也就是距離),並對該距離排序,獲取距離最近的K個數據點,然後判斷這K個數據點的大多數屬於哪一個類別,就認為該新資料點屬於哪一個類別。這也解釋了為什麼K通常取奇數,要是偶數,得到兩個類別的資料點個數都相等,那就尷尬了。
3,KNN分類器的難點是尋找最合適的K值,這個需要用交叉驗證來反覆嘗試,採用具有最大準確率或召回率的K作為最佳K值,這個過程也可以採用GridSearch或RandomSearch來完成。
#################################################################
注:本部分程式碼已經全部上傳到( ofollow,noindex"> 我的github )上,歡迎下載。
參考資料:
1, Python機器學習經典例項,Prateek Joshi著,陶俊傑,陳小莉譯