淺談KNN算法與KD樹

什麼是KNN?

我們先來看看KNN的英文全稱:kNearestNeighbork-NearestNeighbor. 翻譯過來就是K最近的鄰居。KNN是一種分類算法,是數據挖掘分類技術中最簡單的方法之一。所謂K最近鄰,就是k個最近的鄰居的意思,說的是每個樣本都可以用它最接近的k個鄰居來代表。

在這裏插入圖片描述

KNN的核心思想

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

在這裏插入圖片描述
以上圖爲例:
我們判斷綠色是屬於類別1(藍色方塊)還是屬於類別2(紅色三角)
當K=1時即爲K最近鄰,此時搜索範圍內類別1佔比100%,判斷綠色圓圈屬於類別1;
當k=3時,類別2佔比2/3,判斷綠色圓圈屬於類別2

一句話總結:近朱者赤,近墨者黑

KNN的算法流程

1.準備數據,對數據進行預處理
2. 選用合適的數據結構存儲訓練數據和測試元組
3. 設定參數,如k
4.維護一個大小爲k的的按距離由大到小的優先級隊列,用於存儲最近鄰訓練元組。隨機從訓練元組中選取k個元組作爲初始的最近鄰元組,分別計算測試元組到這k個元組的距離,將訓練元組標號和距離存入優先級隊列
5. 遍歷訓練元組集,計算當前訓練元組與測試元組的距離,將所得距離L 與優先級隊列中的最大距離Lmax
6. 進行比較。若L>=Lmax,則捨棄該元組,遍歷下一個元組。若L < Lmax,刪除優先級隊列中最大距離的元組,將當前訓練元組存入優先級隊列。
7. 遍歷完畢,計算優先級隊列中k 個元組的多數類,並將其作爲測試元組的類別。
8. 測試元組集測試完畢後計算誤差率,繼續設定不同的k值重新進行訓練,最後取誤差率最小的k 值。

KNN的三要素

距離度量k值的選擇分類決策規則是k近鄰法的三個基本要素。根據選擇的距離度量(如曼哈頓距離或歐氏距離),可計算測試實例與訓練集中的每個實例點的距離,根據k值選擇k個最近鄰點,最後根據分類決策規則將測試實例分類。

度量距離
在這裏插入圖片描述
在這裏插入圖片描述
K值的選擇
如果選擇較小的K值,就相當於用較小的鄰域中的訓練實例進行預測,學習的近似誤差會減小,只有與輸入實例較近的訓練實例纔會對預測結果起作用,單缺點是學習的估計誤差會增大,預測結果會對近鄰的實例點分成敏感。如果鄰近的實例點恰巧是噪聲,預測就會出錯。換句話說,K值減小就意味着整體模型變複雜,分的不清楚,就容易發生過擬合。

如果選擇較大K值,就相當於用較大鄰域中的訓練實例進行預測,其優點是可以減少學習的估計誤差,但近似誤差會增大,也就是對輸入實例預測不準確,K值得增大就意味着整體模型變的簡單。

近似誤差:可以理解爲對現有訓練集的訓練誤差。

估計誤差:可以理解爲對測試集的測試誤差。

近似誤差關注訓練集,如果k值小了會出現過擬合的現象,對現有的訓練集能有很好的預測,但是對未知的測試樣本將會出現較大偏差的預測。模型本身不是最接近最佳模型。

在這裏插入圖片描述

分類決策規則
k近鄰法中的分類決策規則往往是多數表決,即由輸入實例的k個鄰近的訓練實例中的多數類,決定輸入實例的類。

在這裏插入圖片描述
在這裏插入圖片描述
如上圖所示,我們將唐人街探案這部電影作爲我們要去分類的對象,第一幅圖給出瞭如何計算兩個節點之間的距離的方法,第二幅圖利用該方法得出了唐人街探案與其他樣本的距離,我們找到距離最近的5部影片,這5部影片有4部屬於喜劇,因此我們把唐人街探案這部電影歸結爲喜劇電影。

什麼是Kd-Tree?

實現k近鄰法時,主要考慮的問題是如何對訓練數據進行快速k近鄰搜索,這點在特徵空間的維數大及訓練數據容量大時尤其必要。
    k近鄰法最簡單的實現方法是線性掃描(linear scan),這時要計算輸入實例與每一個訓練實例的距離,當訓練集很大時,計算非常耗時。爲了提高k近鄰法搜索的效率,可以考慮使用特殊的結構存儲訓練數據,以減少計算距離的次數。具體方法很多,kd樹方法(kd樹是存儲k維空間數據的樹結構,這裏的k與k近鄰法的k意義不同)就是其中一種。

原理
k-d樹是每個節點都爲k維點的二叉樹。所有非葉子節點可以視作用一個超平面把空間分割成兩個半空間。節點左邊的子樹代表在超平面左邊的點,節點右邊的子樹代表在超平面右邊的點。選擇超平面的方法如下:每個節點都與k維中垂直於超平面的那一維有關。因此,如果選擇按照x軸劃分,所有x值小於指定值的節點都會出現在左子樹,所有x值大於指定值的節點都會出現在右子樹。這樣,超平面可以用該x值來確定,其法線爲x軸的單位向量。
在這裏插入圖片描述
劃分過程
一個三維k-d樹。 第一次劃分(紅色)把根節點(白色)劃分成兩個節點,然後它們分別再次被劃分(綠色) 爲兩個子節點。最後這四個子節點的每一個都被劃分(藍色) 爲兩個子節點。 因爲沒有更進一步的劃分, 最後得到的八個節點稱爲葉子節點。

上面的圖像可能比較抽象,我們老規矩,舉個栗子先:
假設有6個二維數據點{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},數據點位於二維空間內(如下圖中黑點所示)。kd樹算法就是要確定圖1中這些分割空間的分割線(多維空間即爲分割平面,一般爲超平面)。下面就要通過一步步展示kd樹是如何確定這些分割線的。
在這裏插入圖片描述
1、分別計算x,y方向上數據的方差,得知x方向上的方差最大;
2、根據x軸方向的值2,5,9,4,8,7排序選出中值爲7,所以該node中的data = (7,2)。這樣,該節點的分割超平面就是通過(7,2)並垂直於x軸的直線x = 7;
3、確定左子空間和右子空間。分割超平面x = 7將整個空間分爲兩部分,如下圖所示。x < = 7的部分爲左子空間,包含3個節點{(2,3),(5,4),(4,7)};另一部分爲右子空間,包含2個節點{(9,6),(8,1)}。

在這裏插入圖片描述

劃重點:上圖劃分的第一條線段是過點(7,2)的豎直線段,劃分完該線段後,數據集分了左右。此時重複步驟1,2和3即可以畫出其餘線段。

k-d樹的構建是一個遞歸的過程。然後對左子空間和右子空間內的數據重複根節點的過程就可以得到下一級子節點(5,4)和(9,6)(也就是左右子空間的’根’節點),同時將空間和數據集進一步細分。如此反覆直到空間中只包含一個數據點,如下圖所示:
在這裏插入圖片描述

Kd-Tree的最近鄰查找

(1)將查詢數據Q從根結點開始,按照Q與各個結點的比較結果向下訪問Kd-Tree,直至達到葉子結點。 其中Q與結點的比較指的是將Q對應於結點中的k維度上的值與中值m進行比較,若Q(k) < m,則訪問左子樹,否則訪問右子樹。達到葉子結點時,計算Q與葉子結點上保存的數據之間的距離,記錄下最小距離對應的數據點,記爲當前最近鄰點nearest和最小距離dis。
(2)進行回溯操作,該操作是爲了找到離Q更近的“最近鄰點”。即判斷未被訪問過的分支裏是否還有離Q更近的點,它們之間的距離小於dis。
如果Q與其父結點下的未被訪問過的分支之間的距離小於dis,則認爲該分支中存在離P更近的數據,進入該結點,進行(1)步驟一樣的查找過程,如果找到更近的數據點,則更新爲當前的最近鄰點nearest,並更新dis。
如果Q與其父結點下的未被訪問過的分支之間的距離大於dis,則說明該分支內不存在與Q更近的點。 回溯的判斷過程是從下往上進行的,直到回溯到根結點時已經不存在與P更近的分支爲止。

注:判斷未被訪問過的樹分支中是否還有離Q更近的點,就是判斷"Q與未被訪問的樹分支的距離|Q(k) - m|“是否小於"Q到當前的最近鄰點nearest的距離dis”。從幾何空間上來看,就是判斷以Q爲中心,以dis爲半徑超球面是否與未被訪問的樹分支代表的超矩形相交

舉個栗子

查找點Q(2.1,3.1)
如下圖所示,紅色的點即爲要查找的點。通過圖4二叉搜索,順着搜索路徑很快就能找到當前的最鄰近點(2,3)。
在這裏插入圖片描述

在上述搜索過程中,產生的搜索路徑節點有<(7,2),(5,4),(2,3)>。爲了找到真正的最近鄰,還需要進行’回溯’操作,首先以(2,3)作爲當前最近鄰點nearest,計算其到查詢點Q(2.1,3.1)的距離dis爲0.1414,然後回溯到其父節點(5,4),並判斷在該父節點的其他子節點空間中是否有距離查詢點Q更近的數據點。以(2.1,3.1)爲圓心,以0.1414爲半徑畫圓,如圖6所示。發現該圓並不和超平面y = 4交割,即這裏:|Q(k) - m|=|3.1 - 4|=0.9 > 0.1414,因此不用進入(5,4)節點右子空間中去搜索。

再回溯到(7,2),以(2.1,3.1)爲圓心,以0.1414爲半徑的圓更不會與x = 7超平面交割,因此不用進入(7,2)右子空間進行查找。至此,搜索路徑中的節點已經全部回溯完,結束整個搜索,返回最近鄰點(2,3),最近距離爲0.1414。

總結

Kd樹在維度較小時(比如20、30),算法的查找效率很高,然而當數據維度增大(例如:K≥100),查找效率會隨着維度的增加而迅速下降。假設數據集的維數爲D,一般來說要求數據的規模N滿足N>>2的D次方,才能達到高效的搜索。 爲了能夠讓Kd樹滿足對高維數據的索引,Jeffrey S. Beis和David G. Lowe提出了一種改進算法——Kd-tree with BBF(Best Bin First),該算法能夠實現近似K近鄰的快速搜索,在保證一定查找精度的前提下使得查找速度較快。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章