機器學習--K近鄰 (KNN)算法的原理及優缺點

1、KNN算法原理算法

  K近鄰法(k-nearst neighbors,KNN)是一種很基本的機器學習方法。spring

  它的基本思想是: 在訓練集中數據和標籤已知的狀況下,輸入測試數據,將測試數據的特徵與訓練集中對應的特徵進行相互比較,找到訓練集中與之最爲類似的前K個數據,則該測試數據對應的類別就是K個數據中出現次數最多的那個分類。數組

  因爲KNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來肯定所屬類別的,所以對於類域的交叉或重疊較多的待分樣本集來講,KNN方法較其餘方法更爲適合。KNN算法不只能夠用於分類,還能夠用於迴歸。經過找出一個樣本的k個最近鄰居,將這些鄰居的屬性的平均值賦給該樣本,就能夠獲得該樣本的屬性。更有用的方法是將不一樣距離的鄰居對該樣本產生的影響給予不一樣的權值(weight),如權值與距離成反比。數據結構

  KNN算法的描述:dom

    (1)計算測試數據與各個訓練數據之間的距離;機器學習

    (2)按照距離的遞增關係進行排序;函數

    (3)選取距離最小的K個點;工具

    (4)肯定前K個點所在類別的出現頻率學習

     (5)返回前K個點中出現頻率最高的類別做爲測試數據的預測分類。測試

  算法流程:

    (1) 準備數據,對數據進行預處理。

    (2)選用合適的數據結構存儲訓練數據和測試元組。

    (3)設定參數,如k。

    (4)維護一個大小爲k的的按距離由大到小的優先級隊列,用於存儲最近鄰訓練元組。隨機從訓練元組中選取k個元組做爲初始的最近鄰元組,分別計算測試元組到這k個元組的距離,將訓練元組標號和距離存入優先級隊列。
    (5)遍歷訓練元組集,計算當前訓練元組與測試。元組的距離,將所得距離L 與優先級隊列中的最大距離Lmax。
    (6)進行比較。若L>=Lmax,則捨棄該元組,遍歷下一個元組。若L < Lmax,刪除優先級隊列中最大距離的元組,將當前訓練元組存入優先級隊列。
    (7)遍歷完畢,計算優先級隊列中k 個元組的多數類,並將其做爲測試元組的類別。
    (8)測試元組集測試完畢後計算偏差率,繼續設定不一樣的k值從新進行訓練,最後取偏差率最小的k 值。

  算法優勢:

    (1)簡單,易於理解,易於實現,無需估計參數。

    (2)訓練時間爲零。它沒有顯示的訓練,不像其它有監督的算法會用訓練集train一個模型(也就是擬合一個函數),而後驗證集或測試集用該模型分類。KNN只是把樣本保存起來,收到測試數據時再處理,因此KNN訓練時間爲零。

    (3)KNN能夠處理分類問題,同時自然能夠處理多分類問題,適合對稀有事件進行分類。

    (4)特別適合於多分類問題(multi-modal,對象具備多個類別標籤), KNN比SVM的表現要好。

    (5)KNN還能夠處理迴歸問題,也就是預測。

    (6)和樸素貝葉斯之類的算法比,對數據沒有假設,準確度高,對異常點不敏感。

  算法缺點:

    (1)計算量太大,尤爲是特徵數很是多的時候。每個待分類文本都要計算它到全體已知樣本的距離,才能獲得它的第K個最近鄰點。

    (2)可理解性差,沒法給出像決策樹那樣的規則。

    (3)是慵懶散學習方法,基本上不學習,致使預測時速度比起邏輯迴歸之類的算法慢。

    (4)樣本不平衡的時候,對稀有類別的預測準確率低。當樣本不平衡時,如一個類的樣本容量很大,而其餘類樣本容量很小時,有可能致使當輸入一個新樣本時,該樣本的K個鄰居中大容量類的樣本佔多數。 

    (5)對訓練數據依賴度特別大,對訓練數據的容錯性太差。若是訓練數據集中,有一兩個數據是錯誤的,剛恰好又在須要分類的數值的旁邊,這樣就會直接致使預測的數據的不許確。

 

2、代碼實現

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_blobs  #make_blobs 聚類數據生成器 
from sklearn.neighbors import KNeighborsClassifier   #KNeighborsClassfier K近鄰分類
#sklearn 基於Python語言的機器學習工具,支持包括分類,迴歸,降維和聚類四大機器學習算法。
#  還包括了特徵提取,數據處理和模型評估者三大模塊。
#  sklearn.datasets (衆)數據集;sklearn.neighbors 最近鄰


data=make_blobs(n_samples=5000,centers=5,random_state=8)
# n_samples 待生成樣本的總數,sample 樣本,抽樣
# centers 要生成的樣本中心數
# randon_state 隨機生成器的種子
X,y=data
#返回值,X 生成的樣本數據集;y 樣本數據集的標籤

plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.spring,edgecolor='k')
#c顏色,cmap Colormap實體或者是一個colormap的名字,cmap僅僅當c是一個浮點數數組的時候才使用。

clf=KNeighborsClassifier()
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,0.02),
                  np.arange(y_min,y_max,0.02))
Z=clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z=Z.reshape(xx.shape)
plt.pcolormesh(xx,yy,Z,cmap=plt.cm.Pastel1)
plt.scatter(X[:,0],X[:,1],c=y,cmap=plt.cm.spring,edgecolor='k')
plt.title('KNN-Classifier')
plt.scatter(6.88,4.18,marker='*',s=200,c='r')
plt.xlim([x_min,x_max])


print('模型建好後的運行結果以下:')
print('=======================')
print('新加入樣本的類別是:',clf.predict([[6.72,4.29]]))

print('該模型針對次數據集的分類正確率是:{:.2f}'.format(clf.score(X,y)))

輸出結果:

模型建好後的運行結果以下:
=======================
新加入樣本的類別是: [1]
該模型針對次數據集的分類正確率是:0.96



相關文章
相關標籤/搜索