KD樹是一種對K維空間中的實例點進行存儲以便對其進行快速檢索的樹形數據結構。KD樹其實就是二叉樹,表現爲對K維空間的一個劃分,構造kd樹至關於不斷的用垂直於座標軸的超平面將k維空間切分,構成一系列的k維超矩形區域,即kd樹就是二叉樹在高維上的擴展。kd樹的每一個節點最後對應於一個k維超矩形區域。kd樹搜索的平均計算複雜度是\(O(logN)\)。假如維度是k, 而樣本點一共N個,那麼最好是\(N >> 2^k\)。不然kd樹基於維度須要回溯比較的次數基本等同於線性一個個比較的次數。因此這時候一般會使用如sift中的近似最近鄰方法(best-bin-first search),也就是不須要找到最匹配的那些樣本點,而是放棄必定的精度來加快速度。html
在看別人博客的時候,發現對KD樹有2種不一樣理解,一種如統計學習方法中說的,樹中內部節點也是樣本點,如這裏;而另外一種,樹內部的節點是劃分點,樣本點全都在葉子節點上,如這裏。數據結構
1.1 - 構造過程
這裏先介紹內部節點是樣本點的構造過程:
構造過程;假設訓練集一共\(n\)個樣本點,每一個樣本點特徵維度都是\(k\)。
1)構造根節點:先計算全部樣本第1維組成的向量的中位數。而後將該中位數表示的樣本做爲根節點\(r_0\);將該維度上小於中位數的樣本點劃分到左子樹\(RL\);大於該中位數的樣本點劃分到右子樹\(RR\);
2)構造後續節點:對於步驟1)劃分到左子樹的全部樣本點,按照它們第2維度找中位數,並將中位數對應的樣本做爲該子樹的根節點\(r_{1l}\),將小於該中位數的樣本點劃分到該子樹對應的左子樹,大於的劃分到該子樹對應的右子樹;
經過不斷的找中位數表示的樣本,不斷的對k維空間進行分割,直到兩邊子樹只剩下一個樣本做爲葉子節點。這樣的kd樹是平衡的,不過卻不必定是最優的。app
ps:(1)當劃分層數太深,而維度不夠用時,從頭開始,即從第1維接着開始; (2)樹的每一個節點都對應一個樣本。學習
拿《統計學習方法》例3.2來講,假設訓練集樣本有{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}
第0層根節點,找第1維中位數對應樣本點:[2,4,5,7,8,9],中位數從[5,7]中挑中7,得當前根節點爲(7,2),分得左子樹{(2,3),(4,7),(5,4)};右子樹{(8,1),(9,6)}
第1層根節點,找第2維中位數對應樣本點:左子樹:[3,4,7]-4;右子樹[1,6]-6。分得第1層
左子樹{(2,3)}【(5,4)】{(4,7)};右子樹{(8,1)}【(9,6)】
第2層,由於第一層分割後只剩下每一個根節點對應的左右子樹都只有一個樣本,做爲葉子節點,因此無需再分,結果以下圖:
spa
1.1.1 - 3維空間中的kd樹
rest
1.2 - 搜索過程htm
這裏以全部樣本點爲葉子節點作說明,葉子節點不參與中間的空間劃分 (因懶於畫圖,直接找到了別人的圖[3])
步驟:
blog
2.2 - 往上回溯
ip
完整的過程以下面幾幅圖:get
圖2.5
圖2.6
圖2.7
參考資料:
[1] wiki,https://en.wikipedia.org/wiki/K-d_tree
[2] Beis, J.; Lowe, D. G. (1997). Shape indexing using approximate nearest-neighbour search in high-dimensional spaces. Conference on Computer Vision and Pattern Recognition. Puerto Rico. pp. 1000–1006
[3]Thinh Nguyen, Oregon State University. Lecture 13+: Nearest Neighbor Search (網頁打不開可迅雷下載)