KNN演算法和KD樹

2021-10-02 04:56:50 字數 3526 閱讀 9767

knn(k-nearestneighbor)(鄰近演算法,或者說k最近鄰分類演算法)是資料探勘分類技術中最簡單的方法之一。所謂k最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。

knn演算法的核心思想是如果乙個樣本在特徵空間中的k個最相鄰的樣本中的大多數屬於某乙個類別,則該樣本也屬於這個類別,並具有這個類別上樣本的特性。該方法在確定分類決策上只依據最鄰近的乙個或者幾個樣本的類別來決定待分樣本所屬的類別。 knn方法在類別決策時,只與極少量的相鄰樣本有關。由於knn方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對於類域的交叉或重疊較多的待分樣本集來說,knn方法較其他方法更為適合。

所以,knn演算法的主要流程是假定給定乙個訓練集,其中的例項類別已定,分類時,對新的例項,根據k個最鄰近的例項的類別,通過多數表決的方式進行**,因此,knn演算法不具有顯示的學習過程。

knn演算法流程:

輸入:訓練集t

=t=\left \

t=根據給定的距離度量方法,在訓練集t

tt中找到與x

xx最近鄰的k個點,涵蓋這k個點的x

xx的鄰域記做nk(

x)n_k(x)

nk​(x)

在n k(

x)n_k(x)

nk​(x)

中根據分類決策規則(多數表決)決定x

xx的類別yyy.

knn演算法的基本要素:

k值的選擇:k值得選擇一般通過交叉驗證選擇,當k較小時,模型更複雜,容易發生過擬合現象;k較大時,模型會變得簡單,學習的近似誤差會增大,估計誤差會減小;但是不能取k=m。

距離度量:一般使用三種距離度量方式

閔可夫斯基距離:lp(

xi,x

j)=(

∑l=1

n∣xi

l−xj

l∣p)

1pl_p(x_i,x_j)=(\sum_^|x_i^-x_j^|^p)^}

lp​(xi

​,xj

​)=(

∑l=1

n​∣x

il​−

xjl​

∣p)p

1​歐氏距離:l2(

xi,x

j)=(

∑l=1

n∣xi

l−xj

l∣2)

12l_2(x_i,x_j)=(\sum_^|x_i^-x_j^|^2)^}

l2​(xi

​,xj

​)=(

∑l=1

n​∣x

il​−

xjl​

∣2)2

1​曼哈頓距離:l1(

xi,x

j)=(

∑l=1

n∣xi

l−xj

l∣)l_1(x_i,x_j)=(\sum_^|x_i^-x_j^|)

l1​(xi

​,xj

​)=(

∑l=1

n​∣x

il​−

xjl​

∣)分類決策規則:多數表決

knn優點:

簡單,易於理解,易於實現,無需估計引數,無需訓練;

適合對稀有事件進行分類;

特別適合於多分類問題(multi-modal,物件具有多個類別標籤), knn比svm的表現要好。

knn缺點:

當樣本不平衡時,如乙個類的樣本容量很大,而其他類樣本容量很小時,有可能導致當輸入乙個新樣本時,該樣本的k個鄰居中大容量類的樣本占多數。

計算量較大,因為對每乙個待分類的文字都要計算它到全體已知樣本的距離,才能求得它的k個最近鄰點。

可理解性差,無法給出像決策樹那樣的規則。

kd樹是一種對k維空間中的例項進行儲存以便對其進行快速檢索的樹形資料結構,利用kd樹可以省去對大部分資料點的搜尋,從而減少搜尋的計算量。因此,kd樹可有效提高knn演算法的搜尋效率。

構建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樹:

例如:尋找圖中目標點的最近鄰點

首先假設(4,7)為當前最近鄰點,計算其與目標查詢點的距離為3.202。回溯到(5,4),計算其與查詢點之間的距離為3.041,小於3.202,所以「當前最近鄰點」變成(5,4)。

以目標點(2,4.5)為圓心,以目標點(2,4.5)到「當前最近鄰點」(5,4)的距離(即3.041)為半徑作圓,如上圖所示。可見該圓和y = 4超平面相交,所以需要進入(5,4)左子空間進行查詢,即回溯至(2,3)葉子節點。

(2,3)距離(2,4.5)比(5,4)要近,所以「當前最近鄰點」更新為(2,3),最近距離更新為1.5。

回溯至(7,2),以(2,4.5)為圓心1.5為半徑作圓,並不和x = 7分割超平面交割。

至此,搜尋路徑回溯完。返回最近鄰點(2,3),最近距離1.5。

KNN演算法的KD樹C 實現

kd樹本質上是一種二叉樹,它擁有具備特定排列順序的 節點以便查詢資料,即在二叉排序樹之中,某個 節點左子樹的值均小於 節點的值,而右側均大於 節點的值,如果用中序遍歷這棵樹,它的列印順序將是從小到大遞增的順序。當然剩下的科普就不說了,這也是在pcl庫當中,最常用的輪子之一,處理點雲速度非常快。另外,...

KNN的實現 KD樹

實現knn時,主要考慮的問題是如何對訓練資料進行快速近鄰搜尋.這點在特徵空間的維數大及訓練資料容量大時尤其必要.knn最簡單的實現方法是線性掃瞄 linear scan 這時要計算輸入例項與每乙個訓練例項的距離.當訓練集很大時,計算非常耗時,這種方法是不可行的.為了提高knn搜尋的效率,可以考慮使用...

KD樹演算法

學習了kd樹演算法,用來進行最近鄰匹配,其偽 如下 kd樹演算法的偽 節點結構 node 建立kd樹 輸入 點集list 輸出 kd樹根節點 def build tree list if list is none return none 計算所有點在每一維的方差並排序,從方差最大的維度vi維開始建樹...