1. 程式人生 > >[AI] 最近鄰KNN 及平衡KD 樹 學習筆記

[AI] 最近鄰KNN 及平衡KD 樹 學習筆記

歐氏距離 投票 數據 implement 限制 類模型 技術分享 驗證 數據集

最近鄰算法KNN 學習筆記

定義

為了判定未知樣本的類別,以全部訓練樣本作為代表點,計算未知樣本與所有訓練樣本的距離,並以最近鄰者的類別作為決策未知樣本類別的唯一依據。
選擇未知樣本一定範圍內確定個數的K個樣本,該K個樣本大多數屬於某一類型,則未知樣本判定為該類型。

說明

一般分類方法:
?積極學習法 (決策樹歸納):先根據訓練集構造出分類模型,根據分類模型對測試集分類。
?消極學習法 (基於實例的學習法):推遲建模,當給定訓練元組時,簡單地存儲訓練數據(或稍加處理),一直等到給定一個測試元。
KNN就是一種簡單的消極學習分類方法,它開始並不建立模型,沒有顯式的學習過程。
K近鄰模型由三個基本要素組成:
?距離度量(鄰居判定標準)
?K值的選擇(鄰居數量)
?分類決策規則(確定所屬類別)

算法基本步驟:

  1. 計算待分類點與已知類別的點之間的距離
  2. 按照距離遞增次序排序
  3. 選取與待分類點距離最小的k個點
  4. 確定前k個點所在類別的出現次數
  5. 返回前k個點出現次數最高的類別作為待分類點的預測分類

K值的選擇

如何選擇一個最佳的K值取決於數據。一般情況下,在分類時較大的K值能夠減小噪聲的影響,但會使類別之間的界限變得模糊。

技術分享圖片
如果k取3,從圖可見,待測樣本的3個鄰居在實線的內圓裏,按多數投票結果,它屬於紅色三角形類。但是如果k取5,那麽待測樣本的最鄰近的5個樣本在虛線的圓裏,按表決法,它又屬於藍色正方形類。在實際應用中,K先取一個比較小的數值,再采用交叉驗證法來逐步調整K值,最終選擇適合該樣本的最優的K值。

  • 較小的K值: 優點: 近似誤差(approximation error)會減小,只有與輸入實例較近的(相似的)訓練實例才會對預測結果起作用。 缺點:是“學習”的估計誤差(estimation error)會增大,預測結果會對近鄰的實例點非常敏感
  • 較大的K值: 優點是可以減少學習的估計誤差。 但缺點是學習的近似誤差會增大。這時與輸入實例較遠的(不相似的)訓練實例也會對預測起作用。

在sklearn庫中,k值缺省為5.

距離計算

  1. 一般使用歐氏距離 (兩點的 各維度坐標差 平方和 再開根)
  2. 也可使用其他距離,如:曼哈頓距離 ( 兩點的 各維度坐標差 絕對值之和 )
  3. 更一般的是 Lp 距離 (Minkowski距離)

KNN缺陷

  1. 容易誤判:該算法在分類時有個重要的不足是,當樣本不平衡時,即:一個類的樣本容量很大,而其他類樣本數量很小時,很有可能導致當輸入一個未知樣本時,該樣本的K個鄰居中大數量類的樣本占多數。 但是這類樣本並不接近目標樣本,而數量小的這類樣本很靠近目標樣本。
    技術分享圖片

  2. 計算量大:每一個待分類的樣本都要計算它到全體已知樣本的距離,才能求得它的K個最近鄰點。
    改進: KNN算法的改進方法之一是分組快速搜索近鄰法。其基本思想是:將樣本集按近鄰關系分解成組,給出每組質心的位置,以質心作為代表點,和未知樣本計算距離,選出距離最近的一個或若幹個組,再在組的範圍內應用一般的KNN算法。
    由於並不是將未知樣本與所有樣本計算距離,故該改進算法可以減少計算量,但並不能減少存儲量

KNN計算量優化:KD樹(K-dimension tree)

kd樹(K-dimension tree)是一種對k維空間中的實例點進行存儲以便對其進行快速檢索的樹形數據結構。kd樹是是一種二叉樹,表示對k維空間的一個劃分,構造kd樹相當於不斷地用垂直於坐標軸的超平面將K維空間切分,構成一系列的K維超矩形區域。kd樹的每個結點對應於一個k維超矩形區域。利用kd樹可以省去對大部分數據點的搜索,從而減少搜索的計算量
技術分享圖片

使用二分查找法構建平衡KD tree。

輸入:k維空間數據集T={x1,x2,...,xN},其中xi=(x(1)i,x(2)i,...,x(k)i),i=1,2,...,N;
輸出:kd樹

(1)開始:構造根結點,根結點對應於包含T的k維空間的超矩形區域。選擇x(1) 為坐標軸,以T中所有實例的x(1)坐標的中位數為切分點,將根結點對應的超矩形區域切分為兩個子區域。切分由通過切分點並與坐標軸x(1)垂直的超平面實現。由根結點生成深度為1的左、右子結點:左子結點對應坐標x(1)小於切分點的子區域,右子結點對應於坐標x(1) 大於切分點的子區域。將落在切分超平面上的實例點保存在根結點。

(2)重復。對深度為j的結點,選擇x(l)為切分的坐標軸,l=j%k+1,以該結點的區域中所有實例的x(l)坐標的中位數為切分點,將該結點對應的超矩形區域切分為兩個子區域。切分由通過切分點並與坐標軸x(l)垂直的超平面實現。由該結點生成深度為j+1的左、右子結點:左子結點對應坐標x(l)小於切分點的子區域,右子結點對應坐標x(l)大於切分點的子區域。將落在切分超平面上的實例點保存在該結點。

 例. 給定一個二維空間數據集:T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},構造一個平衡kd樹。
 解:根結點對應包含數據集T的矩形,選擇x(1)軸,6個數據點的x(1)坐標中位數是6,這裏選最接近的(7,2)點,以平面x(1)=7將空間分為左、右兩個子矩形(子結點);接著左矩形以x(2)=4分為兩個子矩形(左矩形中{(2,3),(5,4),(4,7)}點的x(2)坐標中位數正好為4),右矩形以x(2)=6分為兩個子矩形,如此遞歸,最後得到如下圖所示的特征空間劃分和kd樹。
技術分享圖片

搜索kd樹

利用kd樹可以省去對大部分數據點的搜索,從而減少搜索的計算量。下面以搜索最近鄰點為例加以敘述:給定一個目標點,搜索其最近鄰,首先找到包含目標點的葉節點;然後從該葉結點出發,依次回退到父結點;不斷查找與目標點最近鄰的結點,當確定不可能存在更近的結點時終止。這樣搜索就被限制在空間的局部區域上,效率大為提高。

以先前構建好的kd樹為例,查找目標點(3,4.5)的最近鄰點。同樣先進行二叉查找,先從(7,2)查找到(5,4)節點,在進行查找時是由y = 4為分割超平面的,由於查找點為y值為4.5,因此進入右子空間查找到(4,7),形成搜索路徑:(7,2)→(5,4)→(4,7),取(4,7)為當前最近鄰點。以目標查找點為圓心,目標查找點到當前最近點的距離2.69為半徑確定一個紅色的圓。然後回溯到(5,4),計算其與查找點之間的距離為2.06,則該結點比當前最近點距目標點更近,以(5,4)為當前最近點。用同樣的方法再次確定一個綠色的圓,可見該圓和y = 4超平面相交,所以需要進入(5,4)結點的另一個子空間進行查找。(2,3)結點與目標點距離為1.8,比當前最近點要更近,所以最近鄰點更新為(2,3),最近距離更新為1.8,同樣可以確定一個藍色的圓。接著根據規則回退到根結點(7,2),藍色圓與x=7的超平面不相交,因此不用進入(7,2)的右子空間進行查找。至此,搜索路徑回溯完,返回最近鄰點(2,3),最近距離1.8。

技術分享圖片

reference:

  1. KNN算法與Kd樹
  2. KNN之KD樹實現
  3. k-d tree算法原理及實現
  4. 《統計學習方法》 李航 第3章 k近鄰法

[AI] 最近鄰KNN 及平衡KD 樹 學習筆記