【機器學習】【監督學習】【算法01—理論】K近鄰(k-nearest neighbor)

從本節博客開始,我們直接進入具體的機器學習算法以及應用上,筆者暫時的想法是每一個算法都分成三個部分。第一個部分是算法原理,包括算法的描述,數學的內容。第二部分是算法的具體代碼實現細節(沒錯,就是手擼算法)第三部分是一個應用的實例,來加深對於算法的理解。

K-近鄰算法

KNN算法是由Cover和Hart在1968年提出,是一種簡單而典型的機器學習的監督式學習算法。

今天要整理的K-近鄰算法是監督學習中最簡單的一種,如果簡單實現的話,我們只需要提供一個線性搜索的程序就可以很輕鬆的實現這個算法,雖然算法本身原理上並不難,但是仍然有一些值得我們去理解的東西。現在開始吧。

1.算法描述

通常KNN算法都被應用在分類問題上,我們對於算法的初步掌握只需要知道這件事情:

算法輸入:訓練數據集、實例向量x(搭配下方python代碼理解噢)、K值選擇
算法輸出:實例向量x的類別
模型三要素:距離度量,k值的選擇,分類決策規則
輸入
def classify0(inX,dataSet,lables,k):

看起來和它的算法原理本身一樣簡單又簡潔,在對其做正式的算法描述之前,讓我用一個通俗的話來描述這個算法。

  • KNN算法:假定我們已經擁有了一個訓練集,它分佈在我們的模型空間中,每一個訓練樣本,都已知它自己的類別。此時,新來了一個未知類別的實例向量x,我們根據它在空間的位置,找到K個距離它最近的訓練樣本,然後根據這K個樣本中類別分佈,將這個實例向量x劃分到K個類別中最多的類別
  • 正式的定義與算法描述:
    輸入:訓練集T={(x1,y1),(x2,y2).....(xn,yn)}T=\{ (x_{1},y_{1}),(x_{2},y_{2})..... (x_{n},y_{n})\}
    與實例特徵向量x
    輸出:實例特徵向量x的類別

step1:根據給定的距離度量,在訓練集T中找到與x最相近的K個點,涵蓋這k個點的x的鄰域記作:
Nk(x)N_{k}(x)
step2:根據分類決策規則,來決定x的類別y
y=argmaxcj xiNk(x) I(yi=ci),   i=1,2,.....,n;j=1,2....,kj Iyi=ciI=10y=arg \max\limits_{c_{j}} \ \sum\limits_{x_{i}\in N_{k}(x) } \ I(y_{i}=c_{i}), \ \ \ i=1,2,.....,n;j=1,2....,kj\\ \ \\ 其中I是指示函數,若y_{i}=c_{i},I=1,否則爲0

對於argmax函數我解釋一下,這是一個參數函數,我們可以通俗的理解爲,這個函數的作用就是找到在x所對應類別集合中x的類最多的那個類,說起來可能有一些繞,但是作用確實就是一個給y一個確定的類別的作用


2.KNN模型

講到模型,我們很自然的就可以想到直接從模型的三個要素來考慮整個模型的搭建。

(1)距離度量

距離度量決定了我們在計算兩個樣本之間的距離採用的計算方法。
一般來說,我們可以選擇歐式距離,或者使用其他的常用的距離計算方法。關於機器學習中常用的計算距離的方法,有興趣的朋友可以看這一篇博文。此出給出鏈接:

機器學習中那些常用的距離-來自大餅博士X

我們必須要知道的一點就是,在選取不同的距離度量的時候,帶來的分類結果是不一樣的。

(2)k值選擇

在定義k值的時候,我們通常會在一開始選一個比較小的值,然後通過交叉驗證來最終決定我們所選取的K值。
爲什麼k值的選擇如此重要呢?

  • 假設k值選擇過大:

    • 那麼我們一次需要參考許多個鄰近的樣本類別,計算量會增加,不僅如此:如果k值較大,那麼那些實際上距離很遠的,即與實例向量x不相似的樣本,也會進入我們的最終參考範圍。這樣就導致了我們學習誤差增大。
    • 極端情況下:如果k值取得過大,例如取了整個得空間的樣本數量,那麼KNN算法將變得毫無意義。
  • 假設k值選擇過小:

    • 會導致我們只用了很小一部分的訓練樣本來估計我們的實例x,這樣雖然我們保證了只有與實例x極爲相似的樣本纔對結果起作用,但我們的估計誤差會變得很大,因爲實例會對近鄰的類別非常敏感,且參考的範圍非常的小。
    • 極端情況下:我們只選K=1。每次我們只參考一個最近的樣本點,然後判別,這當然是不可取的。

(3)分類決策規則

在我們的算法描述中,我們採用的是多數表決。即k個樣本中,哪個類別佔比最多就判定我們的實例x爲哪個類別。
現在我從以下來證明”多數表決“策略的合理性:

假設分類函數爲:f:Rn{c1,c2.....cK}f: R^{n}\rightarrow\{c_{1},c_{2}.....c_{K} \}
誤分類的概率是:P(Yf(X))=1P(Y=f(X))(1)P(Y\not=f(X))=1-P(Y=f(X)) \tag {1}
我們想要的是,使得誤分類的概率儘可能的小,則需要使得P(Y=f(X))P(Y=f(X))儘可能的大
而(1)式可以化爲:1kxiNk(x)I(yici)=11kxiNk(x)I(yi=ci)\frac{1}{k}\sum\limits_{x_{i}\in N_{k}(x)}I(y_{i}\not=c_{i})=1-\frac{1}{k}\sum\limits_{x_{i}\in N_{k}(x)}I(y_{i}=c_{i})
使xiNk(x)I(yi=ci)即我們需要使得\sum\limits_{x_{i}\in N_{k}(x)}I(y_{i}=c_{i})最大,即多數表決等價於風險最小化

當然,我們也可以根據我們自己的想法,爲K個近鄰元素作爲參考時,添加相應的權值。例如對越近的,那麼認爲它的貢獻值和可信度應該是更高的,賦予其更高的權值。這樣也是可以的。

3.算法的數據結構

瞭解了算法的原理,但是放到計算機上跑數據的時候,仍然還有很大的問題。就是計算量和計算時間的問題,我們不可能等待我們的結果半個月甚至一個月,因此對於算法的實現也是非常重要且有各種優化的需求的。

(1)線性掃描

最容易實現也最簡單的是線性掃描的方法來實現,直接每判定一個實例x的分類的時候,就計算所有樣本與x的距離,再排序,再選k個值,再判定。
但是這樣的計算量非常大。

假設我們的樣本空間有約100萬個樣本,樣本的維度是5維。採用歐式距離,我們需要進行100萬次的歐式距離的計算,其中每次距離的計算,我們要進行五次減法,五次平方,和一次開方。(這個時候可以快速回憶起歐式距離的計算方法)

所以我們的核心任務就是如何快速的找到k個最鄰近的樣本點。如果有計算機基礎的同學,學過數據結構,會想到一個擁有諸多搜索算法的結構,數結構。

(2)KD樹
注意:KD樹的KD指的是 K-dimension,K指的是k維空間,而不是我們討論的KNN中的K值,請注意。

KD樹是一種便於提高我們查找效率的一種數據結構。這部分涉及到數據結構的知識,如果只是初步瞭解KNN算法,則沒有必要一定要了解KD樹的構造以及具體的搜索算法。
因此,我也就在機器學習算法的文章講解中我不做贅述。
如果你想要了解KD樹的構造以及搜索算法,在這篇博文中,我專門爲KD樹寫了一些相關的知識。

KD樹的相關知識,構造以及搜索

(3)Ball Tree

針對高維度的數據,KD樹的效果就不再那麼顯著。(一般是高於20維的數據),這個時候就要採用Ball Tree的方法。

4 小結

我們通過這篇博文可以瞭解到,什麼是KNN算法,具體的算法步驟,以及KNN算法的模型,模型的三要素:距離度量,k值的選擇,分類決策規則,以及我們該選擇怎麼樣的結構去實現這樣的一個算法,並且效率還不差。

雖然KNN算法算是機器學習中最簡單的算法之一,但是仍然不失爲一個經典的算法。我們可以看到,它簡單的部分就在於,它並沒有根據訓練數據得到一個參數。(無需進行模型的訓練)事實上,我們知道它其實就是根據樣本本身的分佈特性,它的樣本空間就是它的模型。這是KNN的一個非常顯著的特點。

優點 缺點
實現簡單 計算量大(尤其是採用線性結構時)
可以用來做分類也可以用來做迴歸 數據不平衡問題,稀缺資源的判斷非常不準確
對數據沒有假設要求 無法給出任何數據的任何信息,過程不可見

之後我們會用一些實際的例子來實現KNN的代碼細節以及幾個關於KNN的實例。

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