决策树:特征分布空间划分方法
前言:懶惰的原因是因?yàn)闀r間太少,不能夠去仔細(xì)的探索學(xué)習(xí),拿來主義喪失了很多快樂!
K近鄰算法的實(shí)現(xiàn):KD樹
原文鏈接:http://blog.csdn.net/v_july_v/article/details/8203674/
2.0、背景
? ?? 之前blog內(nèi)曾經(jīng)介紹過SIFT特征匹配算法,特征點(diǎn)匹配和數(shù)據(jù)庫查、圖像檢索本質(zhì)上是同一個問題,都可以歸結(jié)為一個通過距離函數(shù)在高維矢量之間進(jìn)行相似性檢索的問題,如何快速而準(zhǔn)確地找到查詢點(diǎn)的近鄰,不少人提出了很多高維空間索引結(jié)構(gòu)和近似查詢的算法。
? ? 一般說來,索引結(jié)構(gòu)中相似性查詢有兩種基本的方式:
? ? 同樣,針對特征點(diǎn)匹配也有兩種方法:
- 最容易的辦法就是線性掃描,也就是我們常說的窮舉搜索,依次計(jì)算樣本集E中每個樣本到輸入實(shí)例點(diǎn)的距離,然后抽取出計(jì)算出來的最小距離的點(diǎn)即為最近鄰點(diǎn)。此種辦法簡單直白,但當(dāng)樣本集或訓(xùn)練集很大時,它的缺點(diǎn)就立馬暴露出來了,舉個例子,在物體識別的問題中,可能有數(shù)千個甚至數(shù)萬個SIFT特征點(diǎn),而去一一計(jì)算這成千上萬的特征點(diǎn)與輸入實(shí)例點(diǎn)的距離,明顯是不足取的。
- 另外一種,就是構(gòu)建數(shù)據(jù)索引,因?yàn)閷?shí)際數(shù)據(jù)一般都會呈現(xiàn)簇狀的聚類形態(tài),因此我們想到建立數(shù)據(jù)索引,然后再進(jìn)行快速匹配。索引樹是一種樹結(jié)構(gòu)索引方法,其基本思想是對搜索空間進(jìn)行層次劃分。根據(jù)劃分的空間是否有混疊可以分為Clipping和Overlapping兩種。前者劃分空間沒有重疊,其代表就是k-d樹;后者劃分空間相互有交疊,其代表為R樹。
? ? 而關(guān)于R樹本blog內(nèi)之前已有介紹(同時,關(guān)于基于R樹的最近鄰查找,還可以看下這篇文章:http://blog.sina.com.cn/s/blog_72e1c7550101dsc3.html),本文著重介紹k-d樹。
? ? 1975年,來自斯坦福大學(xué)的Jon Louis Bentley在ACM雜志上發(fā)表的一篇論文:Multidimensional Binary Search Trees Used for Associative Searching 中正式提出和闡述的了如下圖形式的把空間劃分為多個部分的k-d樹。
2.1、什么是KD樹
? ? Kd-樹是K-dimension tree的縮寫,是對數(shù)據(jù)點(diǎn)在k維空間(如二維(x,y),三維(x,y,z),k維(x1,y,z..))中劃分的一種數(shù)據(jù)結(jié)構(gòu),主要應(yīng)用于多維空間關(guān)鍵數(shù)據(jù)的搜索(如:范圍搜索和最近鄰搜索)。本質(zhì)上說,Kd-樹就是一種平衡二叉樹。
? ? 首先必須搞清楚的是,k-d樹是一種空間劃分樹,說白了,就是把整個空間劃分為特定的幾個部分,然后在特定空間的部分內(nèi)進(jìn)行相關(guān)搜索操作。想像一個三維(多維有點(diǎn)為難你的想象力了)空間,kd樹按照一定的劃分規(guī)則把這個三維空間劃分了多個空間,如下圖所示:
2.2、KD樹的構(gòu)建
? ? kd樹構(gòu)建的偽代碼如下圖所示:
? ? 再舉一個簡單直觀的實(shí)例來介紹k-d樹構(gòu)建算法。假設(shè)有6個二維數(shù)據(jù)點(diǎn){(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},數(shù)據(jù)點(diǎn)位于二維空間內(nèi),如下圖所示。為了能有效的找到最近鄰,k-d樹采用分而治之的思想,即將整個空間劃分為幾個小部分,首先,粗黑線將空間一分為二,然后在兩個子空間中,細(xì)黑直線又將整個空間劃分為四部分,最后虛黑直線將這四部分進(jìn)一步劃分。
? ? 6個二維數(shù)據(jù)點(diǎn){(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}構(gòu)建kd樹的具體步驟為:
? ? 與此同時,經(jīng)過對上面所示的空間劃分之后,我們可以看出,點(diǎn)(7,2)可以為根結(jié)點(diǎn),從根結(jié)點(diǎn)出發(fā)的兩條紅粗斜線指向的(5,4)和(9,6)則為根結(jié)點(diǎn)的左右子結(jié)點(diǎn),而(2,3),(4,7)則為(5,4)的左右孩子(通過兩條細(xì)紅斜線相連),最后,(8,1)為(9,6)的左孩子(通過細(xì)紅斜線相連)。如此,便形成了下面這樣一棵k-d樹:
?
? ? k-d樹的數(shù)據(jù)結(jié)構(gòu)
? ? 針對上表給出的kd樹的數(shù)據(jù)結(jié)構(gòu),轉(zhuǎn)化成具體代碼如下所示(注,本文以下代碼分析基于Rob Hess維護(hù)的sift庫):
/** a node in a k-d tree */ struct kd_node {int ki; /**< partition key index *///關(guān)鍵點(diǎn)直方圖方差最大向量系列位置double kv; /**< partition key value *///直方圖方差最大向量系列中最中間模值int leaf; /**< 1 if node is a leaf, 0 otherwise */struct feature* features; /**< features at this node */int n; /**< number of features */struct kd_node* kd_left; /**< left child */struct kd_node* kd_right; /**< right child */ };? ? 也就是說,如之前所述,kd樹中,kd代表k-dimension,每個節(jié)點(diǎn)即為一個k維的點(diǎn)。每個非葉節(jié)點(diǎn)可以想象為一個分割超平面,用垂直于坐標(biāo)軸的超平面將空間分為兩個部分,這樣遞歸的從根節(jié)點(diǎn)不停的劃分,直到?jīng)]有實(shí)例為止。經(jīng)典的構(gòu)造k-d tree的規(guī)則如下:
? ? 對于n個實(shí)例的k維數(shù)據(jù)來說,建立kd-tree的時間復(fù)雜度為O(k*n*logn)。
? ? 以下是構(gòu)建k-d樹的代碼:
struct kd_node* kdtree_build( struct feature* features, int n ) {struct kd_node* kd_root;if( ! features || n <= 0 ){fprintf( stderr, "Warning: kdtree_build(): no features, %s, line %d\n",__FILE__, __LINE__ );return NULL;}//初始化kd_root = kd_node_init( features, n ); //n--number of features,initinalize root of tree.expand_kd_node_subtree( kd_root ); //kd tree expandreturn kd_root; }? ? 上面的涉及初始化操作的兩個函數(shù)kd_node_init,及expand_kd_node_subtree代碼分別如下所示:
static struct kd_node* kd_node_init( struct feature* features, int n ) { //n--number of featuresstruct kd_node* kd_node;kd_node = (struct kd_node*)(malloc( sizeof( struct kd_node ) ));memset( kd_node, 0, sizeof( struct kd_node ) ); //0填充kd_node->ki = -1; //???????kd_node->features = features;kd_node->n = n;return kd_node; } static void expand_kd_node_subtree( struct kd_node* kd_node ) {/* base case: leaf node */if( kd_node->n == 1 || kd_node->n == 0 ){ //葉節(jié)點(diǎn) //偽葉節(jié)點(diǎn)kd_node->leaf = 1;return;}assign_part_key( kd_node ); //get ki,kvpartition_features( kd_node ); //creat left and right children,特征點(diǎn)ki位置左樹比右樹模值小,kv作為分界模值//kd_node中關(guān)鍵點(diǎn)已經(jīng)排序if( kd_node->kd_left )expand_kd_node_subtree( kd_node->kd_left );if( kd_node->kd_right )expand_kd_node_subtree( kd_node->kd_right ); }? ? 構(gòu)建完kd樹之后,如今進(jìn)行最近鄰搜索呢?從下面的動態(tài)gif圖中,你是否能看出些許端倪呢?
? ? k-d樹算法可以分為兩大部分,除了上部分有關(guān)k-d樹本身這種數(shù)據(jù)結(jié)構(gòu)建立的算法,另一部分是在建立的k-d樹上各種諸如插入,刪除,查找(最鄰近查找)等操作涉及的算法。下面,咱們依次來看kd樹的插入、刪除、查找操作。
2.3、KD樹的插入
? ? 元素插入到一個K-D樹的方法和二叉檢索樹類似。本質(zhì)上,在偶數(shù)層比較x坐標(biāo)值,而在奇數(shù)層比較y坐標(biāo)值。當(dāng)我們到達(dá)了樹的底部,(也就是當(dāng)一個空指針出現(xiàn)),我們也就找到了結(jié)點(diǎn)將要插入的位置。生成的K-D樹的形狀依賴于結(jié)點(diǎn)插入時的順序。給定N個點(diǎn),其中一個結(jié)點(diǎn)插入和檢索的平均代價(jià)是O(log2N)。
? ? 下面4副圖(來源:中國地質(zhì)大學(xué)電子課件)說明了插入順序?yàn)?a) Chicago, (b) Mobile, (c) Toronto, and (d) Buffalo,建立空間K-D樹的示例:
? ? 應(yīng)該清楚,這里描述的插入過程中,每個結(jié)點(diǎn)將其所在的平面分割成兩部分。因比,Chicago 將平面上所有結(jié)點(diǎn)分成兩部分,一部分所有的結(jié)點(diǎn)x坐標(biāo)值小于35,另一部分結(jié)點(diǎn)的x坐標(biāo)值大于或等于35。同樣Mobile將所有x坐標(biāo)值大于35的結(jié)點(diǎn)以分成兩部分,一部分結(jié)點(diǎn)的Y坐標(biāo)值是小于10,另一部分結(jié)點(diǎn)的Y坐標(biāo)值大于或等于10。后面的Toronto、Buffalo也按照一分為二的規(guī)則繼續(xù)劃分。
2.4、KD樹的刪除
KD樹的刪除可以用遞歸程序來實(shí)現(xiàn)。我們假設(shè)希望從K-D樹中刪除結(jié)點(diǎn)(a,b)。如果(a,b)的兩個子樹都為空,則用空樹來代替(a,b)。否則,在(a,b)的子樹中尋找一個合適的結(jié)點(diǎn)來代替它,譬如(c,d),則遞歸地從K-D樹中刪除(c,d)。一旦(c,d)已經(jīng)被刪除,則用(c,d)代替(a,b)。假設(shè)(a,b)是一個X識別器,那么,它得替代節(jié)點(diǎn)要么是(a,b)左子樹中的X坐標(biāo)最大值的結(jié)點(diǎn),要么是(a,b)右子樹中x坐標(biāo)最小值的結(jié)點(diǎn)。 也就是說,跟普通二叉樹(包括如下圖所示的紅黑樹)結(jié)點(diǎn)的刪除是同樣的思想:用被刪除節(jié)點(diǎn)A的左子樹的最右節(jié)點(diǎn)或者A的右子樹的最左節(jié)點(diǎn)作為替代A的節(jié)點(diǎn)(比如,下圖紅黑樹中,若要刪除根結(jié)點(diǎn)26,第一步便是用23或28取代根結(jié)點(diǎn)26)。 當(dāng)(a,b)的右子樹為空時,找到(a,b)左子樹中具有x坐標(biāo)最大的結(jié)點(diǎn),譬如(c,d),將(a,b)的左子樹放到(c,d)的右子樹中,且在樹中從它的上一層遞歸地應(yīng)用刪除過程(也就是(a,b)的左子樹) 。 下面來舉一個實(shí)際的例子(來源:中國地質(zhì)大學(xué)電子課件,原課件錯誤已經(jīng)在下文中訂正),如下圖所示,原始圖像及對應(yīng)的kd樹,現(xiàn)在要刪除圖中的A結(jié)點(diǎn),請看一系列刪除步驟: 要刪除上圖中結(jié)點(diǎn)A,選擇結(jié)點(diǎn)A的右子樹中X坐標(biāo)值最小的結(jié)點(diǎn),這里是C,C成為根,如下圖: 從C的右子樹中找出一個結(jié)點(diǎn)代替先前C的位置, 這里是D,并將D的左子樹轉(zhuǎn)為它的右子樹,D代替先前C的位置,如下圖: 在D的新右子樹中,找X坐標(biāo)最小的結(jié)點(diǎn),這里為H,H代替D的位置, 在D的右子樹中找到一個Y坐標(biāo)最小的值,這里是I,將I代替原先H的位置,從而A結(jié)點(diǎn)從圖中順利刪除,如下圖所示: 從一個K-D樹中刪除結(jié)點(diǎn)(a,b)的問題變成了在(a,b)的子樹中尋找x坐標(biāo)為最小的結(jié)點(diǎn)。不幸的是尋找最小x坐標(biāo)值的結(jié)點(diǎn)比二叉檢索樹中解決類似的問題要復(fù)雜得多。特別是雖然最小x坐標(biāo)值的結(jié)點(diǎn)一定在x識別器的左子樹中,但它同樣可在y識別器的兩個子樹中。因此關(guān)系到檢索,且必須注意檢索坐標(biāo),以使在每個奇數(shù)層僅檢索2個子樹中的一個。? ? 從K-D樹中刪除一個結(jié)點(diǎn)是代價(jià)很高的,很清楚刪除子樹的根受到子樹中結(jié)點(diǎn)個數(shù)的限制。用TPL(T)表示樹T總的路徑長度。可看出樹中子樹大小的總和為TPL(T)+N。 以隨機(jī)方式插入N個點(diǎn)形成樹的TPL是O(N*log2N),這就意味著從一個隨機(jī)形成的K-D樹中刪除一個隨機(jī)選取的結(jié)點(diǎn)平均代價(jià)的上界是O(log2N) 。
2.5、KD樹的最近鄰搜索算法
? ? 現(xiàn)實(shí)生活中有許多問題需要在多維數(shù)據(jù)的快速分析和快速搜索,對于這個問題最常用的方法是所謂的kd樹。在k-d樹中進(jìn)行數(shù)據(jù)的查找也是特征匹配的重要環(huán)節(jié),其目的是檢索在k-d樹中與查詢點(diǎn)距離最近的數(shù)據(jù)點(diǎn)。在一個N維的笛卡兒空間在兩個點(diǎn)之間的距離是由下述公式確定:
2.5.1、k-d樹查詢算法的偽代碼
? ? k-d樹查詢算法的偽代碼如下所示:
? ?讀者來信點(diǎn)評@yhxyhxyhx,在“將Kd_point壓入search_path堆棧;”這行代碼后,應(yīng)該是調(diào)到步驟2再往下走二分搜索的邏輯一直到葉結(jié)點(diǎn),我寫了一個遞歸版本的二維kd tree的搜索函數(shù)你對比的看看:
void innerGetClosest(NODE* pNode, PT point, PT& res, int& nMinDis) {if (NULL == pNode)return;int nCurDis = abs(point.x - pNode->pt.x) + abs(point.y - pNode->pt.y);if (nMinDis < 0 || nCurDis < nMinDis){nMinDis = nCurDis;res = pNode->pt;}if (pNode->splitX && point.x <= pNode->pt.x || !pNode->splitX && point.y <= pNode->pt.y)innerGetClosest(pNode->pLft, point, res, nMinDis);elseinnerGetClosest(pNode->pRgt, point, res, nMinDis);int rang = pNode->splitX ? abs(point.x - pNode->pt.x) : abs(point.y - pNode->pt.y);if (rang > nMinDis)return;NODE* pGoInto = pNode->pLft;if (pNode->splitX && point.x > pNode->pt.x || !pNode->splitX && point.y > pNode->pt.y)pGoInto = pNode->pRgt;innerGetClosest(pGoInto, point, res, nMinDis); }? ? 下面,以兩個簡單的實(shí)例(例子來自圖像局部不變特性特征與描述一書)來描述最鄰近查找的基本思路。
2.5.2、舉例:查詢點(diǎn)(2.1,3.1)
? ? 星號表示要查詢的點(diǎn)(2.1,3.1)。通過二叉搜索,順著搜索路徑很快就能找到最鄰近的近似點(diǎn),也就是葉子節(jié)點(diǎn)(2,3)。而找到的葉子節(jié)點(diǎn)并不一定就是最鄰近的,最鄰近肯定距離查詢點(diǎn)更近,應(yīng)該位于以查詢點(diǎn)為圓心且通過葉子節(jié)點(diǎn)的圓域內(nèi)。為了找到真正的最近鄰,還需要進(jìn)行相關(guān)的‘回溯'操作。也就是說,算法首先沿搜索路徑反向查找是否有距離查詢點(diǎn)更近的數(shù)據(jù)點(diǎn)。
? ? 以查詢(2.1,3.1)為例:
2.5.3、舉例:查詢點(diǎn)(2,4.5)
? ? 一個復(fù)雜點(diǎn)了例子如查找點(diǎn)為(2,4.5),具體步驟依次如下:
? ? 上述兩次實(shí)例表明,當(dāng)查詢點(diǎn)的鄰域與分割超平面兩側(cè)空間交割時,需要查找另一側(cè)子空間,導(dǎo)致檢索過程復(fù)雜,效率下降。
一般來講,最臨近搜索只需要檢測幾個葉子結(jié)點(diǎn)即可,如下圖所示:
但是,如果當(dāng)實(shí)例點(diǎn)的分布比較糟糕時,幾乎要遍歷所有的結(jié)點(diǎn),如下所示:
? ? 研究表明N個節(jié)點(diǎn)的K維k-d樹搜索過程時間復(fù)雜度為:tworst=O(kN1-1/k)。
? ? 同時,以上為了介紹方便,討論的是二維或三維情形。但在實(shí)際的應(yīng)用中,如SIFT特征矢量128維,SURF特征矢量64維,維度都比較大,直接利用k-d樹快速檢索(維數(shù)不超過20)的性能急劇下降,幾乎接近貪婪線性掃描。假設(shè)數(shù)據(jù)集的維數(shù)為D,一般來說要求數(shù)據(jù)的規(guī)模N滿足N?2D,才能達(dá)到高效的搜索。所以這就引出了一系列對k-d樹算法的改進(jìn):BBF算法,和一系列M樹、VP樹、MVP樹等高維空間索引樹(下文2.6節(jié)kd樹近鄰搜索算法的改進(jìn):BBF算法,與2.7節(jié)球樹、M樹、VP樹、MVP樹)。
2.6、kd樹近鄰搜索算法的改進(jìn):BBF算法
? ? 咱們順著上一節(jié)的思路,參考統(tǒng)計(jì)學(xué)習(xí)方法一書上的內(nèi)容,再來總結(jié)下kd樹的最近鄰搜索算法:
輸入:以構(gòu)造的kd樹,目標(biāo)點(diǎn)x;輸出:x 的最近鄰
算法步驟如下:
(a)如果該結(jié)點(diǎn)保存的實(shí)例點(diǎn)比當(dāng)前最近點(diǎn)距離目標(biāo)點(diǎn)更近,則更新“當(dāng)前最近點(diǎn)”,也就是說以該實(shí)例點(diǎn)為“當(dāng)前最近點(diǎn)”。
(b)當(dāng)前最近點(diǎn)一定存在于該結(jié)點(diǎn)一個子結(jié)點(diǎn)對應(yīng)的區(qū)域,檢查子結(jié)點(diǎn)的父結(jié)點(diǎn)的另一子結(jié)點(diǎn)對應(yīng)的區(qū)域是否有更近的點(diǎn)。具體做法是,檢查另一子結(jié)點(diǎn)對應(yīng)的區(qū)域是否以目標(biāo)點(diǎn)位球心,以目標(biāo)點(diǎn)與“當(dāng)前最近點(diǎn)”間的距離為半徑的圓或超球體相交:
如果相交,可能在另一個子結(jié)點(diǎn)對應(yīng)的區(qū)域內(nèi)存在距目標(biāo)點(diǎn)更近的點(diǎn),移動到另一個子結(jié)點(diǎn),接著,繼續(xù)遞歸地進(jìn)行最近鄰搜索;
如果不相交,向上回溯。
? ? 如果實(shí)例點(diǎn)是隨機(jī)分布的,那么kd樹搜索的平均計(jì)算復(fù)雜度是O(NlogN),這里的N是訓(xùn)練實(shí)例樹。所以說,kd樹更適用于訓(xùn)練實(shí)例數(shù)遠(yuǎn)大于空間維數(shù)時的k近鄰搜索,當(dāng)空間維數(shù)接近訓(xùn)練實(shí)例數(shù)時,它的效率會迅速下降,一降降到“解放前”:線性掃描的速度。
? ? 也正因?yàn)樯鲜鰇最近鄰搜索算法的第4個步驟中的所述:“回退到根結(jié)點(diǎn)時,搜索結(jié)束”,每個最近鄰點(diǎn)的查詢比較完成過程最終都要回退到根結(jié)點(diǎn)而結(jié)束,而導(dǎo)致了許多不必要回溯訪問和比較到的結(jié)點(diǎn),這些多余的損耗在高維度數(shù)據(jù)查找的時候,搜索效率將變得相當(dāng)之地下,那有什么辦法可以改進(jìn)這個原始的kd樹最近鄰搜索算法呢?
? ? 從上述標(biāo)準(zhǔn)的kd樹查詢過程可以看出其搜索過程中的“回溯”是由“查詢路徑”決定的,并沒有考慮查詢路徑上一些數(shù)據(jù)點(diǎn)本身的一些性質(zhì)。一個簡單的改進(jìn)思路就是將“查詢路徑”上的結(jié)點(diǎn)進(jìn)行排序,如按各自分割超平面(也稱bin)與查詢點(diǎn)的距離排序,也就是說,回溯檢查總是從優(yōu)先級最高(Best Bin)的樹結(jié)點(diǎn)開始。
? ? 針對此BBF機(jī)制,讀者Feng&書童點(diǎn)評道:
? ? 如此,就引出了本節(jié)要討論的kd樹最近鄰搜索算法的改進(jìn):BBF(Best-Bin-First)查詢算法,它是由發(fā)明sift算法的David Lowe在1997的一篇文章中針對高維數(shù)據(jù)提出的一種近似算法,此算法能確保優(yōu)先檢索包含最近鄰點(diǎn)可能性較高的空間,此外,BBF機(jī)制還設(shè)置了一個運(yùn)行超時限定。采用了BBF查詢機(jī)制后,kd樹便可以有效的擴(kuò)展到高維數(shù)據(jù)集上。
? ? 偽代碼如下圖所示(圖取自圖像局部不變特性特征與描述一書):
? ? 還是以上面的查詢(2,4.5)為例,搜索的算法流程為:
2.7、球樹、M樹、VP樹、MVP樹
2.7.1、球樹
? ? 咱們來針對上文內(nèi)容總結(jié)回顧下,針對下面這樣一棵kd樹:
? ? 現(xiàn)要找它的最近鄰。
? ? 通過上文2.5節(jié),總結(jié)來說,我們已經(jīng)知道:
1、為了找到一個給定目標(biāo)點(diǎn)的最近鄰,需要從樹的根結(jié)點(diǎn)開始向下沿樹找出目標(biāo)點(diǎn)所在的區(qū)域,如下圖所示,給定目標(biāo)點(diǎn),用星號標(biāo)示,我們似乎一眼看出,有一個點(diǎn)離目標(biāo)點(diǎn)最近,因?yàn)樗湓谝阅繕?biāo)點(diǎn)為圓心以較小長度為半徑的虛線圓內(nèi),但為了確定是否可能還村莊一個最近的近鄰,我們會先檢查葉節(jié)點(diǎn)的同胞結(jié)點(diǎn),然葉節(jié)點(diǎn)的同胞結(jié)點(diǎn)在圖中所示的陰影部分,虛線圓并不與之相交,所以確定同胞葉結(jié)點(diǎn)不可能包含更近的近鄰。
2、于是我們回溯到父節(jié)點(diǎn),并檢查父節(jié)點(diǎn)的同胞結(jié)點(diǎn),父節(jié)點(diǎn)的同胞結(jié)點(diǎn)覆蓋了圖中所有橫線X軸上的區(qū)域。因?yàn)樘摼€圓與右上方的矩形(KD樹把二維平面劃分成一個一個矩形)相交...
? ? 如上,我們看到,KD樹是可用于有效尋找最近鄰的一個樹結(jié)構(gòu),但這個樹結(jié)構(gòu)其實(shí)并不完美,當(dāng)處理不均勻分布的數(shù)據(jù)集時便會呈現(xiàn)出一個基本沖突:既邀請樹有完美的平衡結(jié)構(gòu),又要求待查找的區(qū)域近似方形,但不管是近似方形,還是矩形,甚至正方形,都不是最好的使用形狀,因?yàn)樗麄兌加薪恰?/p>
? ? ? ??
? ? 什么意思呢?就是說,在上圖中,如果黑色的實(shí)例點(diǎn)離目標(biāo)點(diǎn)星點(diǎn)再遠(yuǎn)一點(diǎn),那么勢必那個虛線圓會如紅線所示那樣擴(kuò)大,以致與左上方矩形的右下角相交,既然相交了,那么勢必又必須檢查這個左上方矩形,而實(shí)際上,最近的點(diǎn)離星點(diǎn)的距離很近,檢查左上方矩形區(qū)域已是多余。于此我們看見,KD樹把二維平面劃分成一個一個矩形,但矩形區(qū)域的角卻是個難以處理的問題。
? ? 解決的方案就是使用如下圖所示的球樹:
先從球中選擇一個離球的中心最遠(yuǎn)的點(diǎn),然后選擇第二個點(diǎn)離第一個點(diǎn)最遠(yuǎn),將球中所有的點(diǎn)分配到離這兩個聚類中心最近的一個上,然后計(jì)算每個聚類的中心,以及聚類能夠包含它所有數(shù)據(jù)點(diǎn)所需的最小半徑。這種方法的優(yōu)點(diǎn)是分裂一個包含n個殊絕點(diǎn)的球的成本只是隨n呈線性增加。
? ? 使用球樹找出給定目標(biāo)點(diǎn)的最近鄰方法是,首先自上而下貫穿整棵樹找出包含目標(biāo)點(diǎn)所在的葉子,并在這個球里找出與目標(biāo)點(diǎn)最靠近的點(diǎn),這將確定出目標(biāo)點(diǎn)距離它的最近鄰點(diǎn)的一個上限值,然后跟KD樹查找一樣,檢查同胞結(jié)點(diǎn),如果目標(biāo)點(diǎn)到同胞結(jié)點(diǎn)中心的距離超過同胞結(jié)點(diǎn)的半徑與當(dāng)前的上限值之和,那么同胞結(jié)點(diǎn)里不可能存在一個更近的點(diǎn);否則的話,必須進(jìn)一步檢查位于同胞結(jié)點(diǎn)以下的子樹。
? ? 如下圖,目標(biāo)點(diǎn)還是用一個星表示,黑色點(diǎn)是當(dāng)前已知的的目標(biāo)點(diǎn)的最近鄰,灰色球里的所有內(nèi)容將被排除,因?yàn)榛疑虻闹行狞c(diǎn)離的太遠(yuǎn),所以它不可能包含一個更近的點(diǎn),像這樣,遞歸的向樹的根結(jié)點(diǎn)進(jìn)行回溯處理,檢查所有可能包含一個更近于當(dāng)前上限值的點(diǎn)的球。
? ? 球樹是自上而下的建立,和KD樹一樣,根本問題就是要找到一個好的方法將包含數(shù)據(jù)點(diǎn)集的球分裂成兩個,在實(shí)踐中,不必等到葉子結(jié)點(diǎn)只有兩個胡數(shù)據(jù)點(diǎn)時才停止,可以采用和KD樹一樣的方法,一旦結(jié)點(diǎn)上的數(shù)據(jù)點(diǎn)打到預(yù)先設(shè)置的最小數(shù)量時,便可提前停止建樹過程。
? ? 也就是上面所述,先從球中選擇一個離球的中心最遠(yuǎn)的點(diǎn),然后選擇第二個點(diǎn)離第一個點(diǎn)最遠(yuǎn),將球中所有的點(diǎn)分配到離這兩個聚類中心最近的一個上,然后計(jì)算每個聚類的中心,以及聚類能夠包含它所有數(shù)據(jù)點(diǎn)所需的最小半徑。這種方法的優(yōu)點(diǎn)是分裂一個包含n個殊絕點(diǎn)的球的成本只是隨n呈線性增加(注:本小節(jié)內(nèi)容主要來自參考條目19:數(shù)據(jù)挖掘?qū)嵱脵C(jī)器學(xué)習(xí)技術(shù),[新西蘭]Ian H.Witten 著,第4章4.7節(jié))。
2.7.2、VP樹與MVP樹簡介
? ??高維特征向量的距離索引問題是基于內(nèi)容的圖像檢索的一項(xiàng)關(guān)鍵技術(shù),目前經(jīng)常采用的解決辦法是首先對高維特征空間做降維處理,然后采用包括四叉樹、kd樹、R樹族等在內(nèi)的主流多維索引結(jié)構(gòu),這種方法的出發(fā)點(diǎn)是:目前的主流多維索引結(jié)構(gòu)在處理維數(shù)較低的情況時具有比較好的效率,但對于維數(shù)很高的情況則顯得力不從心(即所謂的維數(shù)危機(jī)) 。
? ? 實(shí)驗(yàn)結(jié)果表明當(dāng)特征空間的維數(shù)超過20 的時候,效率明顯降低,而可視化特征往往采用高維向量描述,一般情況下可以達(dá)到10^2的量級,甚至更高。在表示圖像可視化特征的高維向量中各維信息的重要程度是不同的,通過降維技術(shù)去除屬于次要信息的特征向量以及相關(guān)性較強(qiáng)的特征向量,從而降低特征空間的維數(shù),這種方法已經(jīng)得到了一些實(shí)際應(yīng)用。
? ??然而這種方法存在不足之處采用降維技術(shù)可能會導(dǎo)致有效信息的損失,尤其不適合于處理特征空間中的特征向量相關(guān)性很小的情況。另外主流的多維索引結(jié)構(gòu)大都針對歐氏空間,設(shè)計(jì)需要利用到歐氏空間的幾何性質(zhì),而圖像的相似性計(jì)算很可能不限于基于歐氏距離。這種情況下人們越來越關(guān)注基于距離的度量空間高維索引結(jié)構(gòu)可以直接應(yīng)用于高維向量相似性查詢問題。
? ? 度量空間中對象之間的距離度量只能利用三角不等式性質(zhì),而不能利用其他幾何性質(zhì)。向量空間可以看作由實(shí)數(shù)坐標(biāo)串組成的特殊度量空間,目前針對度量空間的高維索引問題提出的索引結(jié)構(gòu)有很多種大致可以作如下分類,如下圖所示:
? ? ?讀者點(diǎn)評:
? ? 更多內(nèi)容請參見論文1:DIST ANCE-BASED INDEXING FOR HIGH-DIMENSIONAL METRIC SP ACES,作者:Tolga Bozkaya & Meral Ozsoyoglu,及論文2:基于度量空間高維索引結(jié)構(gòu)VP-tree及MVP-tree的圖像檢索,王志強(qiáng),甘國輝,程起敏。
? ? 當(dāng)然,如果你覺得上述論文還不夠滿足你胃口的話,這里有一大堆nearest neighbor algorithms相關(guān)的論文可供你看:http://scholar.google.com.hk/scholar?q=nearest+neighbor+algorithms&btnG=&hl=zh-CN&as_sdt=0&as_vis=1(其中,這篇可以看下:Spill-Trees,An investigation of practical approximate nearest neighbor algorithms)。
總結(jié)
以上是生活随笔為你收集整理的决策树:特征分布空间划分方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ***K近邻Survey-Distanc
- 下一篇: ML一些简单的资源