KD樹核心思想簡介


Kd-樹 其實是K-dimension tree的縮寫,是對數據點在k維空間中划分的一種數據結構。其實,Kd-樹是一種平衡二叉樹。

舉一示例:

假設有六個二維數據點 = {(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},數據點位於二維空間中。為了能有效的找到最近鄰,Kd-樹采用分而治之的思想,即將整個空間划分為幾個小部分。六個二維數據點生成的Kd-樹的圖為:

2D 3D KD-tree

對於擁有n個已知點的kD-Tree,其復雜度如下:

  1. 構建:O(log2n)
  2. 插入:O(log n)
  3. 刪除:O(log n)
  4. 查詢:O(n1-1/k+m) m---每次要搜索的最近點個數

一 Kd-樹的構建

Kd-樹是一個二叉樹,每個節點表示的是一個空間范圍。下表表示的是Kd-樹中每個節點中主要包含的數據結構。Range域表示的是節點包含的空間范圍。Node-data域就是數據集中的某一個n維數據點。分割超面是通過數據點Node-Data並垂直於軸split的平面,分割超面將整個空間分割成兩個子空間。令split域的值為i,如果空間Range中某個數據點的第i維數據小於Node-Data[i],那么,它就屬於該節點空間的左子空間,否則就屬於右子空間。Left,Right域分別表示由左子空間和右子空間空的數據點構成的Kd-樹。

域名

數據類型

描述

Node-Data

數據矢量

數據集中某個數據點,是n維矢量

Range

空間矢量

該節點所代表的空間范圍

Split

整數

垂直於分割超面的方向軸序號

Left

Kd-tree

由位於該節點分割超面左子空間內所有數據點構成的Kd-樹

Right

Kd-tree

由位於該節點分割超面左子空間內所有數據點構成的Kd-樹

Parent

Kd-tree

父節點

構建Kd-樹的偽碼為:

算法:構建Kd-tree

輸入:數據點集Data_Set,和其所在的空間。

輸出:Kd,類型為Kd-tree

1 if data-set is null ,return 空的Kd-tree

2 調用節點生成程序

(1)確定split域:對於所有描述子數據(特征矢量),統計他們在每個維度上的數據方差,挑選出方差中最大值,對應的維就是split域的值。數據方差大說明沿該坐標軸方向上數據點分散的比較開。這個方向上,進行數據分割可以獲得最好的分辨率。

(2)確定Node-Data域,數據點集Data-Set按照第split維的值排序,位於正中間的那個數據點 被選為Node-Data,Data-Set` =Data-Set\Node-data

3 dataleft = {d 屬於Data-Set` & d[:split]<=Node-data[:split]}

Left-Range ={Range && dataleft}

dataright = {d 屬於Data-Set` & d[:split]>Node-data[:split]}

Right-Range ={Range && dataright}

4 :left =由(dataleft,LeftRange)建立的Kd-tree

設置:left的parent域(父節點)為Kd

:right =由(dataright,RightRange)建立的Kd-tree

設置:right的parent域為kd。

如上例中,

(1)確定:split 域=x,6個數據點在x,y 維度上的數據方差為39,28.63.在x軸方向上的方差大,所以split域值為x。

(2)確定:Node-Data=(7,2),根據x維上的值將數據排序,6個數據的中值為7,所以node-data域為數據點(7,2)。這樣該節點的分割超面就是通過(7,2)並垂直於:split=x軸的直線x=7.

(3)左子空間和右子空間,分割超面x=7將整個空間分為兩部分。x<=7 為左子空間,包含節點(2,3),(5,4),(4,7),另一部分為右子空間。包含節點(9,6),(8,1)

這個構建過程是一個遞歸過程。重復上述過程,直至只包含一個節點。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM