1. 程式人生 > >機器學習---演算法---K-近鄰演算法

機器學習---演算法---K-近鄰演算法

轉自:https://www.cnblogs.com/Rosanna/p/3615507.html

 K-近鄰和最近鄰(K=1)是模式識別中常用的分類方法,K-近鄰演算法思想是找到與當前樣本相鄰的K個有標籤樣本,然後通過投票決定此樣本的類別。例如下圖中如何分類未知的綠色圓圈呢?

      例如我們可以取K=3個臨近的樣本時,通過投票(紅色兩個大於藍色一個),從而將綠色圓圈歸於紅色三角一類。

 

一.基於例項的學習

      K-近鄰和區域性加權迴歸就是基於例項的學習。基於例項的學習過程只是簡單的儲存已知的訓練資料,當遇到新的待分類樣本時,將從訓練資料中挑選出一系列相似的樣本,並用來分類新的樣本。

      與常見的分類演算法(如神經網路)不同的是,基於例項的方法可以為不同的待分類樣本建立不同的函式逼近。只建立目標函式的區域性逼近,而不是建立在整個樣本空間都表現良好的逼近。所以,當目標函式很複雜但可以用不太複雜的區域性逼近描述時,用基於例項的學習方法會有很大的優勢。

      同時我們可以看到基於例項的學習方法一個很明顯的缺點就是它分類新樣本開銷很大,因為幾乎所有的計算都放生在分類時,而不是第一次遇到訓練樣本時。另外還有一個缺點就是從訓練資料中尋找相似樣本時,我們一般都是計算樣本的所有屬性的距離,當樣本只依賴於其中幾個屬性時,新的待分類樣本會離真正相似樣本很遠,從而發生錯誤分類。

 

二.K-近鄰演算法

      假設一個樣本的特徵向量為{a1(x),a2(x),…,an(x)},ar(x)表示樣本x的第r個屬性值。那麼兩個樣本xi,xj之間的距離可以表示為

d(xi,xj)=sqrt(sum(ar(xi)-ar(xj))2)   r=1~n

        K-緊鄰的演算法流程很簡單:

  • 訓練:講訓練樣本加入train_set;
  • 分類:對一個新的待分類樣本xq
  •          計算train_set中最靠近xq
    的k個樣本,記為x1,x2,...,xk
  •          返回最多的類別資訊

 

      關於K值的選擇,摘自李航《統計學習方法》:

  • 如果選擇較小的K值,就相當於用較小的領域中的訓練例項進行預測,“學習”近似誤差會減小,只有與輸入例項較近或相似的訓練例項才會對預測結果起作用,與此同時帶來的問題是“學習”的估計誤差會增大,換句話說,K值的減小就意味著整體模型變得複雜,容易發生過擬合
  • 如果選擇較大的K值,就相當於用較大領域中的訓練例項進行預測,其優點是可以減少學習的估計誤差,但缺點是學習的近似誤差會增大。這時候,與輸入例項較遠(不相似的)訓練例項也會對預測器作用,使預測發生錯誤,且K值的增大就意味著整體的模型變得簡單
  • K=N,則完全不足取,因為此時無論輸入例項是什麼,都只是簡單的預測它屬於在訓練例項中最多的累,模型過於簡單,忽略了訓練例項中大量有用資訊。

 

三.K-近鄰演算法改進

      針對K-近鄰演算法的不足可以做出幾點改進:

1.距離加權

      本文一開始的示例圖中,若K=5,那麼綠色圈圈就會被分類到藍色方塊中。為了解決這個問題,可以對K個近鄰的貢獻加權,權值為距離平方的倒數:

wi=1/(d(xi,xj)2

      即距離越遠,權值越小,距離越近,權值越大。

2.對每個屬性加權

      並不是樣本所有的屬性都是有助於分類的,例如一個樣本由20個屬性描述,但這些屬性中只有2個與分類有關。在這種情況下,一個測試樣本可能在20維的空間中與它想死的訓練樣本相距很遠,結果導致了錯誤分類。解決的辦法就是給每個屬性加權,這相當於按比例縮放歐式空間的座標軸,縮短不太相關的屬性的座標軸,拉長對應於更相關的屬性的座標軸,可以通過交叉驗證自動決定。

3.建立索引

      K-近鄰推遲了所有的計算,直到來了一個新的測試樣本,分類時需要大量計算。一個高效的解決辦法就是對儲存的訓練樣本進行索引,在增加一定儲存開銷的情況下更快速的找到K個臨近樣本,比如Kd-tree[參考2]。

 

四.總結

1.KNN的優點:

  • 理論成熟,演算法簡單;
  • 可用於非線性分類;
  • 對outlier不敏感。

2.KNN的缺點:

  • 不平衡樣本效果不好;
  • 預測計算量大;
  • 佔用記憶體多。

 

參考資料:

1.《機器學習》

2.從K近鄰演算法、距離度量談到KD樹、SIFT+BBF演算法