1. 程式人生 > >分類:K最鄰近分類

分類:K最鄰近分類

      K最鄰近分類是分類方法中比較簡單的一種,下面對其進行介紹

    1.任務

       分類

     2.結構

       K最鄰近分類模型屬於“基於記憶”的非引數區域性模型,這種模型並不是立即利用訓練資料建立模型(也即是說K最鄰近分類器並不需要訓練),資料不再被函式和引數所替代,在對測試樣例進行型別估計的時候,找出和其距離最接近的K個樣例,以其中數量最多的類別來確定該樣例的類標號。

       K最鄰近分類模型的結構可以用下圖來說明。在該圖中叉號表示輸入的待分類樣例,對其分類時選定一個距離範圍(虛線圓圈表示的範圍),在該範圍內包含有K個樣例(除去待分類樣例外,這裡K=5),這裡所說的距離並不專指距離度量(如曼哈頓距離、歐氏距離等),它可以是任意一種鄰近度度量(在我的博文《資料測量與相似性分析》中有介紹),此時最鄰近的5個樣例中,有3個“+”例,2個“-”例,故待分類樣例的類別定位“+”。為了便於確定類別,K一般取奇數。

                                                                  

        

     3.評分函式

        K最鄰近分類方法中使用的評分函式為常用的誤分類率。

     4.搜尋、優化方法

       4.1 K值選取

       K最鄰近分類方法的分類過程可知,K值對模型的誤分類率影響較大。K較小時,相當於用較小鄰域中的樣例進行預測,“學習”的近似誤差會減小,但是“學習“的估計誤差會增大,且對鄰域內的樣例非常敏感,若鄰近的樣例中包含部分噪聲,預測結果就會出錯,K

較大時的情況則相反。

        總的來說,K值減小意味著整體模型變複雜,容易發生過擬合,K值增大意味著模型變簡單,導致忽略“訓練”樣例中一些有用資訊,預測誤分類率會增高。在應用中,一般K取較小的值(例如sklearn庫中最鄰近分類器KNeighborsClassifier中K預設為5),可以通過交叉驗證法選擇一個合適的K

       4.2 最鄰近樣例搜尋

       由於K最鄰近分類器不需要利用樣例進行訓練,因此關鍵點就集中在如何快速進行K鄰近樣例搜尋,這在特徵空間維數大和樣例資料量大時非常重要。一種容易想到的方法是對所有樣例進行線性搜尋,但顯然這在特徵空間高維數、樣例量大時不可取。有很多方法可以提高搜尋效率,這裡介紹其中的一種——kd樹(kd tree)方法。

        kd樹(也是一種二叉樹)是一種對 k 維空間中的樣例進行儲存以便對其進行快速檢索的樹形結構,在特徵空間為一維時,平衡二叉樹是一個不錯的選擇,但是當特徵空間為多維時,平衡二叉樹就無能為力了,此時 kd 樹就派上用場了。

       構造kd樹       

       kd樹的構造過程大致為:首先構造一個根節點,選擇 k 維特徵空間中的一個變數x^{1},依據在變數x^{1}上的取值的中位數劃分樣例集(大於或等於中位值、小於中位值),形成左子樹和右子樹,這個根節點就類似於一個矩形超平面,將樣例集劃分到平面左右兩側。接著再選擇一個變數x^{2},按照樣例在變數x^{2}上取值的中位值分別對左子樹、右子樹中的樣例進行劃分,這個過程相當於在之前被根節點一分為二的左、右超平面內,分別用基於各自空間內x^{2}上中位數的矩形超平面再次將子空間進行劃分,重複這個過程,直到kd樹的每個結點上只包含一個樣例為止(即葉子結點,從幾何空間上看,即劃分後兩個子區域內沒有例項存在)。這個過程中有幾點需要單獨強調:

      (1) 在這個過程中,劃分空間時變數優先選擇策略可以為:依據子空間內(根節點時為整個樣例空間)樣例在該變數上取值波動程度(即方差),波動大的優先選擇。當然,也可以是隨機選擇。

      (2) 當所有變數都被用來劃分樣例、劃分仍未結束時,需要接著用所有變數再進行一次劃分,不斷重複該過程,直到劃分停止。

      (3) 假設當前選擇用變數x^{k}進行劃分,那麼本次劃分是在各子空間單獨進行的,即各子空間內本次劃分時,在變數x^{k}上選值是依據該子空間內樣例的中位值。

      (4) kd樹上對同一層深度的樣例劃分時,必須使用同一變數,也即是說在一次劃分中,各子空間必須使用同一變數。

      (5) 劃分值(矩形超平面位置)選擇的是各子空間內樣例在變數上取值的中位數,這種劃分策略保證生成的kd樹是平衡的。

       kd樹的構造演算法為:

      輸入:k維空間資料集T={x_{1},x_{2},...,x_{N}},其中 x_{i}=(x_{i}^{(1)},x_{i}^{(2)},...,x_{i}^{(k)})

      輸出:kd

  • 開始:構造根節點,根節點對應於包含Tk維空間的超矩形區域。選擇x^{(1)}為座標軸,以T中所有例項的x^{(1)}座標的中位數為切分點,將根節點對應的超矩形區域切分為兩個子區域。切分由通過切分點並與座標軸x^{(1)}垂直的超平面實現。對由根結點生成深度為1的左、右子結點,左子結點對應座標x^{(1)}小於切分點的子區域,右子結點對應於座標x^{(1)}大於切分點的子區域。將落在切分超平面上的例項點儲存為根節點。
  • 重複:對深度為j的結點,選擇x^{(m)}為切分的座標軸,m=j(mod)k+1,以該結點的區域中所有例項的x^{(m)}座標的中位數為切分點,將該結點對應的超矩形區域分為兩個子區域。切分由通過切分點並與座標軸x^{(m)}垂直的超平面實現。由該結點生成深度為j+1的左、右子結點:左子結點對應座標x^{(m)}小於切分點的區域,右子結點對應座標x^{(m)}大於切分點的區域。將落在切分超平面上的例項點儲存在該結點。
  • 結束:直到兩個區域沒有例項存在時停止。

      舉一個kd數構造的例子。給定一個二維空間資料集T

                                                T=\left \{ (2,3)^{T},(5,4)^{T},(9,6)^{T},(4,7)^{T},(8,1)^{T},(7,2)^{T} \right \}

       kd樹的構造過程為:選擇x^{(1)}軸,6個數據點x^{(1)}座標的中位數為7(5也可以),以平面x^{(1)}=7將空間劃分為左、右兩個子矩形(子結點),左子矩形以x^{(2)}=4平面一分為二,右子矩形以x^{(2)}=6一分為二,如此遞迴,得到下圖(左)所示的特徵空間劃分,下圖(右)所示的kd樹。

  

      搜尋kd樹 

       kd樹的構造過程來看,可以省去對大部分資料點的搜尋,從而減少搜尋的時間。給定一個目標點(即待分類樣例),先找到包含該目標點的葉子結點,然後依次回退到父結點,在這個過程中不斷查詢與目標點最鄰近的樣例,當確定不可能存在更近的結點時,結束搜尋過程。這個過程可以用下圖來說明(因此次搜尋過程不涉及圖中左下子區域中的點,因此未畫出)

                                          
       圖中共有A、B、C、D、E、F 5個樣例點,其中點F(綠色)輸入的待分類樣例點,點A(根節點,紅色,橢圓)在變數x^{1}的矩形超平面上,點B(紅色,圓形)在變數x^{1}的矩形超平面下方,點C、D、E、F 均在變數x^{1}的矩形超平面上方。點C(藍色,橢圓)在變數x^{2}的矩形超平面上,點D(藍色,圓形)在變數x^{2}的矩形超平面左邊,點E、F在變數x^{2}的矩形超平面右邊。

      首先找到點F所在的葉子結點,即點E(點F與點E在同一區域內),此時點E為最鄰近點,計算點F與點E間的距離,得到r1(藍色虛線)。接著回到父結點C上,計算父結點C與點F間的距離,發現該距離大於r1,故最鄰近點仍然為點E,然後以點F為圓心,r1為半徑作圓(藍色線條的圓),若該圓與變數x^{2}上的矩形超平面相交,則需要對父結點C的另一個子區域(左子樹)內的點進行搜尋,因為這表明其中可能存在更鄰近點;若圓(藍色線條的圓)與變數x^{2}上的矩形超平面不相交,則不必在父結點的另一個子空間內搜尋。由於此時圓(藍色線條的圓)與變數x^{2}上的矩形超平面相交,因此需要計算點D與點F間的距離r2(紅色虛線),結果發現r2<r1,故此時點D是最鄰近點。

      接著再回到結點C的父結點A上,計算點A與點F間的距離並與r2比較,發現該距離大於r2,故點D仍然為最鄰近點,然後以點F為圓心,r2為半徑作圓,該圓與變數x^{1}的矩形超平面不相交,故不需要再對結點A的左子樹(變數x^{1}的矩形超平面下半區域)內的點進行搜尋,即點B不可能是最鄰近點。

       至此為止,在本例中搜索過程結束,需要說明的是,本例中的圓在實際多維特徵空間中為超球體,判斷超球體與分類矩形超平面是否相交的方法為:待分類點(目標點)與分類超矩形平面的距離(即在當前分類變數x^{k}上,待分類點與父結點在x^{k}上取值的差值的絕對值)是否大於超球體半徑。在實際中也只需要依照該過程不斷重複,直至搜尋到根節點。

       kd樹上最鄰近點的搜尋演算法為:

  •  kd樹上找出包含目標點 x 的葉子結點:從根節點出發,遞迴的向下訪問 kd樹,若目標點 x 當前維的座標小於切分點的座標,則移動到左子樹點,否則移動到右子樹點,直至子結點為葉子結點為止。
  • 以此葉子結點為最鄰近點
  • 遞迴的向上回退,在每個結點進行一下操作:
    • 如果該結點儲存的例項點比當前最近點距離目標點更近,則以該例項點為“當前最近點”
    • 當前最近點一定存在於該結點的一個子結點對應的區域。檢查該子結點父結點的另一子結點對應的區域是否有更近點。具體的,檢查另一子結點對應的區域是否與以目標點為球心、以目標點與“當前最近點”間距離為半徑的超球體相交。如果相交,可能在另一子結點對應的區域記憶體在距離目標點更近的點,移動到另一子結點。接著遞迴的進行最鄰近搜尋。如果不想交,則向上回退。
  • 當退回到根結點時,結束搜尋,最後的“當前最近點”即為 x 的最鄰近點。

    

    以上的過程是K=1的情況,對於K>1的情況,搜尋的方式和K=1時一樣,但在找最近的K個點時,首先要保證找到數量足夠的點,在前K次搜尋時不必考慮距離問題,直接將這K個點當做“當前最近K個點”,接下來的搜尋就要考慮距離問題了,以這K個點中最遠距離作為“當前最近距離”,當找到更近的點時,對“當前最近距離”進行更新。

   5.小結

    從kd樹的構造、搜尋過程來看,最鄰近分類器也是需要訓練、構造kd樹的,當然,若是採用線性搜尋的方式則不需要。