關於knn演算法,對特徵空間進行劃分的方法為計算新的輸入例項與訓練例項之間的距離,因為在特徵空間中2個特徵例項的相似程度可以用距離來表示。一般我們採用的是歐式距離,也就是說每個新的輸入例項都需要與所有的訓練例項計算一次距離並排序。當訓練集非常大的時候,計算就非常耗時、耗記憶體,導致演算法的效率降低。以上是對knn演算法的簡單理解。
kd樹(k-dimensional樹的簡稱)
是一種對k維空間中的例項點進行儲存以便對其進行快速搜尋的二叉樹結構。利用kd樹可以省去對大部分資料點的搜尋,從而減少搜尋的計算量。
kd 樹是每個節點均為k維數值點的二叉樹,其上的每個節點代表乙個超平面,該超平面垂直於當前劃分維度的座標軸,並在該維度上將空間劃分為兩部分,一部分在其左子樹,另一部分在其右子樹。即若當前節點的劃分維度為d,其左子樹上所有點在d維的座標值均小於當前值,右子樹上所有點在d維的座標值均大於等於當前值,本定義對其任意子節點均成立。
集合(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)。
構建根節點時,此時的切分維度為x,如上點集合在x維從小到大排序為(2,3),(4,7),(5,4),(7,2),(8,1),(9,6);其中值為(7,2)。(注:2,4,5,7,8,9在數學中的中值為(5 + 7)/2=6,但因該演算法的中值需在點集合之內,所以中值計算用的是 len(points)//2=3, points[3]=(7,2) )
(2,3),(4,7),(5,4)掛在(7,2)節點的左子樹,(8,1),(9,6)掛在(7,2)節點的右子樹。
構建(7,2)節點的左子樹時,點集合(2,3),(4,7),(5,4)此時的切分維度為y,中值為(5,4)作為分割平面,(2,3)掛在其左子樹,(4,7)掛在其右子樹。
構建(7,2)節點的右子樹時,點集合(8,1),(9,6)此時的切分維度也為y,中值為(9,6)作為分割平面,(8,1)掛在其左子樹。至此k-d tree構建完成。
根據上面的步驟,kd樹將二維空間的劃分展示出來:
對於kd-tree這樣一棵二叉樹,我們首先需要確定怎樣劃分左子樹和右子樹,即乙個k維資料是依據什麼被劃分到左子樹或右子樹的。
在構造1維bst樹時,乙個1維資料根據其與樹的根結點和中間結點進行大小比較的結果來決定是劃分到左子樹還是右子樹,同理,我們也可以按照這樣的方式,將乙個k維資料與kd-tree的根結點和中間結點進行比較,只不過不是對k維資料進行整體的比較,而是選擇某乙個維度di,然後比較兩個k維數在該維度di上的大小關係,即每次選擇乙個維度di來對k維資料進行劃分,相當於用乙個垂直於該維度di的超平面將k維資料空間一分為二,平面一邊的所有k維資料在di維度上的值小於平面另一邊的所有k維資料對應維度上的值。也就是說,我們每選擇乙個維度進行如上的劃分,就會將k維資料空間劃分為兩個部分,如果我們繼續分別對這兩個子k維空間進行如上的劃分,又會得到新的子空間,對新的子空間又繼續劃分,重複以上過程直到每個子空間都不能再劃分為止。以上就是構造kd-tree的過程,上述過程中涉及到兩個重要的問題:
1、每次對子空間的劃分時,怎樣確定在哪個維度上進行劃分。
2、在某個維度上進行劃分時,怎樣確保在這一維度上的劃分得到的兩個子集合的數量盡量相等,即左子樹和右子樹中的結點個數盡量相等。
最簡單的方法就是輪著來,即如果這次選擇了在第i維上進行資料劃分,那下一次就在第j(j-i)維上進行劃分
如果乙個k維資料集合的分布像木條一樣,那就是說明這k維資料在木條較長方向代表的維度上,這些資料的分布散得比較開,數學上來說,就是這些資料在該維度上的方差(invariance)比較大,換句話說,正因為這些資料在該維度上分散的比較開,我們就更容易在這個維度上將它們劃分開,因此,這就引出了我們選擇維度的另一種方法:最大方差法(max invarince),即每次我們選擇維度進行劃分時,都選擇具有最大方差維度。
假設當前我們按照最大方差法選擇了在維度i上進行k維資料集s的劃分,此時我們需要在維度i上將k維資料集合s劃分為兩個子集合a和b,子集合a中的資料在維度i上的值都小於子集合b中。首先考慮最簡單的劃分法,即選擇第乙個數作為比較物件(即劃分軸,pivot),s中剩餘的其他所有k維資料都跟該pivot在維度i上進行比較,如果小於pivot則劃a集合,大於則劃入b集合。把a集合和b集合分別看做是左子樹和右子樹,那麼我們在構造乙個二叉樹的時候,當然是希望它是一棵盡量平衡的樹,即左右子樹中的結點個數相差不大。而a集合和b集合中資料的個數顯然跟pivot值有關,因為它們是跟pivot比較後才被劃分到相應的集合中去的。好了,現在的問題就是確定pivot了。給定乙個陣列,怎樣才能得到兩個子陣列,這兩個陣列包含的元素個數差不多且其中乙個子陣列中的元素值都小於另乙個子陣列呢?方法很簡單,找到陣列中的中值(即中位數,median),然後將陣列中所有元素與中值進行比較,就可以得到上述兩個子陣列。同樣,在維度i上進行劃分時,pivot就選擇該維度i上所有資料的中值,這樣得到的兩個子集合資料個數就基本相同了。
(1) 在k維資料集合中選擇具有最大方差的維度k,然後在該維度上選擇中值m為pivot對該資料集合進行劃分,得到兩個子集合;同時建立乙個樹結點node,用於儲存;
(2)對兩個子集合重複(1)步驟的過程,直至所有子集合都不能再劃分為止;如果某個子集合不能再劃分時,則將該子集合中的資料儲存到葉子結點(leaf node)。
(1)將查詢資料q從根結點開始,按照q與各個結點的比較結果向下訪問kd-tree,直至達到葉子結點。
其中q與結點的比較指的是將q對應於結點中的k維度上的值與m進行比較,若q(k) < m,則訪問左子樹,否則訪問右子樹。達到葉子結點時,計算q與葉子結點上儲存的資料之間的距離,記錄下最小距離對應的資料點,記為當前「最近鄰點」pcur和最小距離dcur。
(2)進行回溯(backtracking)操作,該操作是為了找到離q更近的「最近鄰點」。即判斷未被訪問過的分支裡是否還有離q更近的點,它們之間的距離小於dcur。
如果q與其父結點下的未被訪問過的分支之間的距離小於dcur,則認為該分支中存在離p更近的資料,進入該結點,進行(1)步驟一樣的查詢過程,如果找到更近的資料點,則更新為當前的「最近鄰點」pcur,並更新dcur。
如果q與其父結點下的未被訪問過的分支之間的距離大於dcur,則說明該分支內不存在與q更近的點
機器學習KNN演算法中的KD樹搜尋
引用部落格 1.kd樹的構建 統計學習方法 第三章 2.kd樹的最臨近搜尋方法 樹的效果顯示為 在k d樹中進行資料的查詢也是特徵匹配的重要環節,其目的是檢索在k d樹中與查詢點距離最近的資料點。這裡先以乙個簡單的例項來描述最鄰近查詢的基本思路。星號表示要查詢的點 2.1,3.1 通過二叉搜尋,順著...
KNN演算法和KD樹
knn k nearestneighbor 鄰近演算法,或者說k最近鄰分類演算法 是資料探勘分類技術中最簡單的方法之一。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。knn演算法的核心思想是如果乙個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某乙個類別,...
KNN演算法的KD樹C 實現
kd樹本質上是一種二叉樹,它擁有具備特定排列順序的 節點以便查詢資料,即在二叉排序樹之中,某個 節點左子樹的值均小於 節點的值,而右側均大於 節點的值,如果用中序遍歷這棵樹,它的列印順序將是從小到大遞增的順序。當然剩下的科普就不說了,這也是在pcl庫當中,最常用的輪子之一,處理點雲速度非常快。另外,...