1. 程式人生 > >統計學習方法筆記(一):K近鄰法的實現:kd樹

統計學習方法筆記(一):K近鄰法的實現:kd樹

  實現k近鄰演算法時,首要考慮的問題是如何對訓練資料進行快速的k近鄰搜尋。這點在特徵空間的維數大於訓練資料容量時尤為重要。

  1. 構造kd樹
      kd 樹是一種對k為空間中的例項點進行儲存的一邊對其進行快速檢索的樹形資料結構。kd樹是二叉樹,表示對k維空間的一個劃分(partition)。構造kd樹相當於不斷地用垂直於座標軸的超平面將k維空間切分。構成一系列的k維超矩形區域。kd樹的每個結點對應於一個k維的超矩形區域。
      構建kd樹的方法: 構造跟結點,使跟結點對應於k維空間中包含所有例項點的超矩形區域;通過下面的遞迴方法,不斷地對k為空間進行切分,生產子節點。在超矩形區域(結點)上選擇一個座標軸和在此座標軸上的一個切分點,確定一個超平面,這個超平面通過選定的切分點並垂直於選定的座標軸,將當前超矩形區域切分為左右兩個子區域(子結點);這時,例項唄分到兩個子區域。這個過程直到子區域內沒有例項時終止(終止時的結點為葉結點)。在此過程中,將例項儲存在相應的結點上。
      通常,依次選擇座標軸對空間劃分,選擇訓練例項點在選定的座標軸的中位數為切分點,這樣得到的kd樹是平衡的。注意

    ,平衡的kd樹搜尋時的效率未必是最優的。
    演算法:(構造平衡kd樹)
    輸入: k維空間資料集T={x1,x2,…,xN},其中x1=(xi(1),xi(2),…,xi(k))T,i=1,2,…,N
    輸出: kd
    (1)開始:構造根節點,根節點對應於包含T的k維空間的超矩形區域。
      選擇x(1)為座標軸,以T中所有例項的x(1)座標的中位數為一切分點,將根節點對應的超矩形區域切分為兩個子區域。切分由通過切分點並與座標軸x(1)垂直的超平面實現。
    由根節點生成深度為1 的左、右子節點:左子節點對應座標x(1)小於切分點的子區域,右子節點對應於座標x(1)大於切分點的子區域。
      將落在切分超平面上的例項點儲存在根節點。
    (2)重複:對深度為j
    的結點,選擇x(1)為切分的座標軸,l=j(mod k)+1,以該節點的區域中的所有例項的x(1)座標的中位數為切分點,將該結點對應超矩形區域切分成兩個子區域。切分由通過切分點並與座標軸x(1)垂直的超平面實現。
      由根節點生成深度為j+1的左、右子節點:左子節點對應座標x(1)小於切分點的子區域,右子節點對應於座標x(1)大於切分點的子區域。
    (3)直到兩個子區域沒有例項存在時停止。從而形成kd樹的區域劃分。

  2. 搜尋kd
      下面介紹如何利用kd樹進行k近鄰搜尋。這裡以最近鄰為例加以敘述。
      給定一個目標點,搜尋其最近鄰。首先找到包含目標點的葉節點;然後從該葉節點出發,一次回退到父節點;不斷查詢與目標點最近鄰的結點,當確定不可能存在更近的結點時終止。這樣搜尋酒杯限制在空間的區域性區域上,效率大為提高。
      包含目標點的葉節點對應包含目標點的最小超矩形區域。一次葉節點的例項點作為當前的最近點。目標點的最近鄰一定是以目標點為中心並通過當前最近鄰點的超球體內部。然後返回當前結點的父節點,如果父節點的另一子節點的超矩形區域與超球體相交,那麼在相交的區域內尋找與目標點更近的例項點。如果存在這樣的點,將此點作為新的當前最近鄰點。演算法轉到更上一級的父節點,繼續上述過程,如果父節點的另一子節點的超矩形區域與超球體不想交,或不存在比當前更近點更近的點,則停止搜尋。
    kd樹的最近鄰搜尋:

      
    輸入: 已構造的kd樹;目標點x
    輸出: x的最近鄰。

    (1) 在kd樹中找出包含目標點x的葉結點:從根結點出發,遞迴的向下訪問kd樹。若目標點當前維的座標值小於切分點的座標值,則移動到左子結點,否則移動到右子結點。直到子結點為葉結點為止;
    (2) 以此葉結點為“當前最近點”;
    (3) 遞迴的向上回退,在每個結點進行以下操作:
      (a) 如果該結點儲存的例項點比當前最近點距目標點更近,則以該例項點為“當前最近點”;
      (b) 當前最近點一定存在於該結點一個子結點對應的區域。檢查該子結點的父結點的另一個子結點對應的區域是否有更近的點。具體的,檢查另一個子結點對應的區域是否與以目標點為球心、以目標點與“當前最近點”間的距離為半徑的超球體相交。
      如果相交,可能在另一個子結點對應的區域記憶體在距離目標更近的點,移動到另一個子結點。接著,遞迴的進行最近鄰搜尋。如果不相交,向上回退。
    (4) 當回退到根結點時,搜尋結束。最後的“當前最近點”即為x的最近鄰點。