根據knn每次需要**乙個點時,我們都需要計算訓練資料集裡每個點到這個點的距離,然後選出距離最近的k個點進行投票。當資料集很大時,這個計算成本非常高,針對n個樣本,d個特徵的資料集,其演算法複雜度為o(dn2)。
kd樹:為了避免每次都重新計算一遍距離,演算法會把距離資訊儲存在一棵樹裡,這樣在計算之前從樹裡查詢距離資訊,盡量避免重新計算。其基本原理是,如果a和b距離很遠,b和c距離很近,那麼a和c的距離也很遠。有了這個資訊,就可以在合適的時候跳過距離遠的點。
最近鄰域搜尋(nearest-neighbor lookup)
kd樹(k-dimension tree)是一種對k維空間中的例項點進行儲存以便對其進行快速檢索的樹形資料結構。kd樹是一種二叉樹,表示對k維空間的乙個劃分,構造kd樹相當於不斷地用垂直於座標軸的超平面將k維空間切分,構成一系列的k維超矩形區域。kd樹的每個結點對應於乙個k維超矩形區域。利用kd樹可以省去對大部分資料點的搜尋,從而減少搜尋的計算量。
模擬「二分查詢」:給出一組資料:[9 1 4 7 2 5 0 3 8],要查詢8。如果挨個查詢(線性掃瞄),那麼將會把資料集都遍歷一遍。而如果排一下序那資料集就變成了:[0 1 2 3 4 5 6 7 8 9],按前一種方式我們進行了很多沒有必要的查詢,現在如果我們以5為分界點,那麼資料集就被劃分為了左右兩個「簇」 [0 1 2 3 4]和[6 7 8 9]。
因此,根本就沒有必要進入第乙個簇,可以直接進入第二個簇進行查詢。把二分查詢中的資料點換成k維資料點,這樣的劃分就變成了用超平面對k維空間的劃分。空間劃分就是對資料點進行分類,「挨得近」的資料點就在乙個空間裡面。
(1)構造根結點,使根結點對應於k維空間中包含所有例項點的超矩形區域;
(2)通過遞迴的方法,不斷地對k維空間進行切分,生成子結點。在超矩形區域上選擇乙個座標軸和在此座標軸上的乙個切分點,確定乙個超平面,這個超平面通過選定的切分點並垂直於選定的座標軸,將當前超矩形區域切分為左右兩個子區域(子結點);這時,例項被分到兩個子區域。
(3)上述過程直到子區域內沒有例項時終止(終止時的結點為葉結點)。在此過程中,將例項儲存在相應的結點上。
(4)通常,迴圈的選擇座標軸對空間切分,選擇訓練例項點在座標軸上的中位數為切分點,這樣得到的kd樹是平衡的(平衡二叉樹:它是一棵空樹,或其左子樹和右子樹的深度之差的絕對值不超過1,且它的左子樹和右子樹都是平衡二叉樹)。
kd樹中每個節點是乙個向量,和二叉樹按照數的大小劃分不同的是,kd樹每層需要選定向量中的某一維,然後根據這一維按左小右大的方式劃分資料。在構建kd樹時,關鍵需要解決2個問題:
(1)選擇向量的哪一維進行劃分;
(2)如何劃分資料;
第乙個問題簡單的解決方法可以是隨機選擇某一維或按順序選擇,但是更好的方法應該是在資料比較分散的那一維進行劃分(分散的程度可以根據方差來衡量)。
第二個問題中,好的劃分方法可以使構建的樹比較平衡,可以每次選擇中位數來進行劃分。
給定乙個二維空間資料集:t=,構造乙個平衡kd樹。
(1)思路引導:
根結點對應包含資料集t的矩形,選擇x(1)軸,6個資料點的x(1)座標中位數是6,這裡選最接近的(7,2)點,以平面x(1)=7將空間分為左、右兩個子矩形(子結點);接著左矩形以x(2)=4分為兩個子矩形(左矩形中點的x(2)座標中位數正好為4),右矩形以x(2)=6分為兩個子矩形,如此遞迴,最後得到如下圖所示的特徵空間劃分和kd樹。
假設標記為星星的點是 test point, 綠色的點是找到的近似點,在回溯過程中,需要用到乙個佇列,儲存需要回溯的點,在判斷其他子節點空間中是否有可能有距離查詢點更近的資料點時,做法是以查詢點為圓心,以當前的最近距離為半徑畫圓,這個圓稱為候選超球(candidate hypersphere),如果圓與回溯點的軸相交,則需要將軸另一邊的節點都放到回溯佇列裡面來。
image-20190213224152601
樣本集3.2.1 查詢點(2.1,3.1)
在(7,2)點測試到達(5,4),在(5,4)點測試到達(2,3),然後search_path中的結點為,從search_path中取出(2,3)作為當前最佳結點nearest, dist為0.141;
然後回溯至(5,4),以(2.1,3.1)為圓心,以dist=0.141為半徑畫乙個圓,並不和超平面y=4相交,如上圖,所以不必跳到結點(5,4)的右子空間去搜尋,因為右子空間中不可能有更近樣本點了。
於是再回溯至(7,2),同理,以(2.1,3.1)為圓心,以dist=0.141為半徑畫乙個圓並不和超平面x=7相交,所以也不用跳到結點(7,2)的右子空間去搜尋。
至此,search_path為空,結束整個搜尋,返回nearest(2,3)作為(2.1,3.1)的最近鄰點,最近距離為0.141。
3.2.2 查詢點(2,4.5)
在(7,2)處測試到達(5,4),在(5,4)處測試到達(4,7)【優先選擇在本域搜尋】,然後search_path中的結點為,從search_path中取出(4,7)作為當前最佳結點nearest, dist為3.202;
然後回溯至(5,4),以(2,4.5)為圓心,以dist=3.202為半徑畫乙個圓與超平面y=4相交,所以需要跳到(5,4)的左子空間去搜尋。所以要將(2,3)加入到search_path中,現在search_path中的結點為;另外,(5,4)與(2,4.5)的距離為3.04 < dist = 3.202,所以將(5,4)賦給nearest,並且dist=3.04。
回溯至(2,3),(2,3)是葉子節點,直接平判斷(2,3)是否離(2,4.5)更近,計算得到距離為1.5,所以nearest更新為(2,3),dist更新為(1.5)
回溯至(7,2),同理,以(2,4.5)為圓心,以dist=1.5為半徑畫乙個圓並不和超平面x=7相交, 所以不用跳到結點(7,2)的右子空間去搜尋。
至此,search_path為空,結束整個搜尋,返回nearest(2,3)作為(2,4.5)的最近鄰點,最近距離為1.5。
二維K D樹的構造及搜尋
k d k dimensional 樹在很多聚類演算法中都有應用,例如cure演算法。k d樹的構造說明請參考j outsider的博文,本文這裡只給出其構造 如下 主程式 clc clear 讀取資料檔案,生成點矩陣 fileid fopen d matlabfile k d tree test....
利用kd樹實現最近鄰搜尋
輸入 已經構造的kd樹,目標點x 輸出 x的最近鄰 1在kd樹中找出包含目標點x的葉節點 從根結點出發,遞迴地向下訪問kd樹。若目標點x當前維的座標小於切分點的座標,則移動到左葉子結點,否則移動到右葉子結點。直到子節點為葉節點為止。2以此葉節點為 當前最近點 3遞迴地向上回退,在每個結點進行以下操作...
機器學習KNN演算法中的KD樹搜尋
引用部落格 1.kd樹的構建 統計學習方法 第三章 2.kd樹的最臨近搜尋方法 樹的效果顯示為 在k d樹中進行資料的查詢也是特徵匹配的重要環節,其目的是檢索在k d樹中與查詢點距離最近的資料點。這裡先以乙個簡單的例項來描述最鄰近查詢的基本思路。星號表示要查詢的點 2.1,3.1 通過二叉搜尋,順著...