1. 定義
所謂 K 近鄰算法(K-Nearest Neighbor)簡稱 KNN 算法。即給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最近鄰的 K 個實例(也就是 K 個鄰居),這 K 個實例的多數屬於某個類,就把該輸入實例分到這個類中。
如上圖所示,有兩個不同的樣本數據,分別用藍色的正方形和紅色的三角形表示,綠色的圓表示待分類的數據。
問題:綠色的圓應該屬於哪一類?
KNN 的思想就是:物以類聚,從綠色圓的鄰居下手,我們可以認爲,綠色的圓總是與它的鄰居相似。
- 如果 K = 1,綠色的圓與紅色的三角最接近,歸爲紅色三角這一類,這也就是所謂的最近鄰。
- 如果 K =3,綠色的圓有三個鄰居,兩個紅色的三角,一個藍色的正方形,紅色的多,將綠色的圓歸爲紅色類。
- 如果 K =5,綠色的圓有五個鄰居,兩個紅色的三角,一個藍色的正方形,藍色的多,將綠色的圓歸爲藍色類。
問題來了:K = 3 時 綠色的小球歸爲了紅色一類,K =5 時綠色的小球歸爲了藍色的一類,那麼我們該選擇 K =3 還是該選擇 K=5 呢?這個問題在後面會探討。
另一個問題也來了:物以類聚,人以羣分。小明有三個要好的好朋友是好人,有四個不太要好的朋友是壞人,那麼小明算是好人還是壞人呢?顯然,不能因爲有四個不太要好的壞人朋友就忽略其有三個要好的朋友這一事實。說白了,就是當 K=5 時,兩個紅色的三角距離綠色小球更近,而三個藍色正方形距離小球較遠,他們應該有個權重,權重的大小與距離的大小成反比。至於實際中會不會這樣處理,得查一查。
2. 近鄰距離的度量
既然可以根據實例點的鄰居來決定實例屬於哪一類,那麼如何尋找鄰居,哪些是鄰居就自然而然需要解決了。
如何尋找鄰居,最簡單的就是:
對現有的所有樣本數據進行遍歷,找到待分類實例的 K 個鄰居。
那麼下一個丞待解決的問題就是:如何衡量兩個實例是不是鄰居?當然,我們很容易想到,距離近的就是鄰居,所以我們需要一個方法來衡量距離的概念。
假設兩個 n 維向量分別爲:
- 閔科夫斯基距離
範數
在優化方法中經常會遇到範數的概念,其中所述的 p 範數就可以理解爲閔科夫斯基距離,如下所示:
||x||p=∑i|xi|p−−−−−−−√p
將其擴展爲兩個 n 維向量的閔科夫斯基距離,表示如下:
||d||p=∑i|xi−yi|p−−−−−−−−−−−√p - 曼哈頓距離
當閔科夫斯基距離中的 p=1 時,表示的距離就是曼哈頓距離,或稱爲街區距離:
||d||=∑i|xi−yi|
再看 1 範數的形式:
||x||=∑i|xi| - 歐式距離
當閔科夫斯基距離中的 p=2 時,表示的距離就是歐式:
||d||2=∑i|xi−yi|2−−−−−−−−−−−√
再看 2 範數的形式:
||x||2=∑i|xi|2−−−−−−−√ - 切比雪夫距離
當閔科夫斯基距離中的 p=∞ 時,表示的距離就是切比雪夫距離:
||d||∞=maxi|xi−yi|
再看無窮範數的形式:
||x||∞=maxi|xi|
以上是常用的一些距離衡量指標,還有很多其他的形式,如:
1. 漢明距離
2. 夾角餘弦(餘弦相似度)
3. 皮爾遜係數(Pearson 相關係數)
4. 標準化歐式距離
5. 馬氏距離
6. 巴氏距離
7. 傑卡德相似係數
3. K 值的選擇
從第一部分可以看出:K 值的不同可能導致不同的分類結果。那麼什麼樣的 K 值合適呢,這裏參考 《統計學習方法》3.2.3的陳述:
- 如果選擇較小的 K 值,就相當於用較小的鄰域中的訓練實例進行預測,“學習”近似誤差會減小,只有與輸入實例較近的(相似的)訓練實例纔會對預測結果起作用。但缺點是“學習”的估計誤差會增大,換句話說,K值的減小就意味着整體模型變得複雜,容易發生過擬合;
- 如果選擇較大的K值,就相當於用較大領域中的訓練實例進行預測,其優點是可以減少學習的估計誤差,但缺點是學習的近似誤差會增大。這時候,與輸入實例較遠(不相似的)訓練實例也會對預測器作用,使預測發生錯誤,且K值的增大就意味着整體的模型變得簡單。
- 如果K=N,那麼無論輸入實例是什麼,都只是簡單的預測它屬於在訓練實例中最多的類,模型過於簡單,忽略了訓練實例中大量有用信息。完全不足取。
在應用中,K 值一般選擇比較小的值。通常採用交叉驗證法來選取最優的 K 值。
4. kd-樹
k-dimension tree,是一種對數據點在 k 維空間中劃分的一種數據結構,主要應用與多維空間關鍵數據的搜索。本質上仍舊是一顆二叉樹。
構造平衡 kd樹:
輸入:k爲空間數據集
- 開始:構造根節點
選擇x(1) 爲座標軸,選擇 T 中所有x(1) 座標的中位數爲切分點。在子結點對應座標小於切分點的子區域,右子結點對應於座標軸x(1) 大於切分點的子區域。 - 重複:
對深度爲 j 的結點,選擇x(l) 爲切分的座標軸,其中l=j(modk)+1 。由該結點生成深度爲 j+1 的左右子結點。 - 知道兩個子區域沒有實例存在爲止。
例:給定一個二維空間數據集:
如下圖所示:
圖中的
- 隨着樹的深度增加,循環的選取座標軸,作爲切分超平面的法向量。
- 每次均把中位數對應的實例作爲切分點。
5. kd樹的最近鄰搜索
輸入:以構造的 kd 樹,目標點 x
輸出: x 的最近鄰
- 在 kd 樹中找出包含目標點 x 的葉結點:從根結點出發,遞歸地向下訪問 kd 樹,若目標點 x 當前維座標小於切分點座標,移動到左子結點,否則移動到右子結點,直到結束。
- 以此結點爲“當前最近點”
- 遞歸的向上回退,在每個結點進行如下操作:
- 如果該結點保存的實例點比當前最近點距離目標點更近,則以該實例點爲“當前最近點”
- 當前最近點一定存在於該結點一個子結點對應的區域,檢查該子結點的父結點的另一個子結點對應的區域是否有更近的點。
具體地,檢查另一子結點對應的區域是否與以目標點爲球心,以目標點與“當前最近點”間的距離爲半徑的球相交。如果相交,可能另一子結點對應的區域內存在距離目標點更近的點,移動到另一子結點。接着,遞歸地進行最近鄰搜索;如果不相交,向上回退。
- 當回退到根結點時,搜索結束,最後的“當前最近點”即爲 x 的最近鄰點。
例:給定下圖所示的 kd 樹,根結點爲 A,其子結點爲 B、C等,另有一個輸入的目標實例點 S,求 S 的最近鄰。
- 找到包含 S 的葉結點D,以 D 作爲近似最近鄰。
- 搜索 D 的兄弟結點 F,結點 F 的區域與圓不相交,不可能有最近鄰點。
- 返回上一級父結點 A,在 B 的兄弟結點 C 內搜索,結點 C 的區域與圓相交;該區域在圓內的實例有點 E,點 E 比點 D 更近,成爲最近鄰近似。
- 結束。
6. 參考
《統計學習方法》第三章 - 李航
《最近鄰居法》