一文搞懂k近鄰(k-NN)算法(一)

前幾天和德川一起在學習會上講解了k-NN算法,這裏進行總結一下,力爭用最通俗的語言講解以便有利於更多同學的理解。

本文目錄如下:

1.k近鄰算法的基本概念,原理以及應用

2.k近鄰算法中k的選取,距離的度量以及特徵歸一化的必要性

3.k近鄰法的實現:kd樹原理的講解

4.kd樹詳細例子講解

5.kd樹的不足以及最差情況舉例

6.k近鄰方法的一些個人總結

一.k近鄰算法的基本概念,原理以及應用

k近鄰算法是一種基本分類和迴歸方法。本篇文章只討論分類問題的k近鄰法。

K近鄰算法,即是給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最鄰近的K個實例,這K個實例的多數屬於某個類,就把該輸入實例分類到這個類中。(這就類似於現實生活中少數服從多數的思想)根據這個說法,咱們來看下引自維基百科上的一幅圖:

如上圖所示,有兩類不同的樣本數據,分別用藍色的小正方形和紅色的小三角形表示,而圖正中間的那個綠色的圓所標示的數據則是待分類的數據。這也就是我們的目的,來了一個新的數據點,我要得到它的類別是什麼?好的,下面我們根據k近鄰的思想來給綠色圓點進行分類。

  • 如果K=3,綠色圓點的最鄰近的3個點是2個紅色小三角形和1個藍色小正方形,少數從屬於多數,基於統計的方法,判定綠色的這個待分類點屬於紅色的三角形一類。
  • 如果K=5,綠色圓點的最鄰近的5個鄰居是2個紅色三角形和3個藍色的正方形,還是少數從屬於多數,基於統計的方法,判定綠色的這個待分類點屬於藍色的正方形一類。

從上面例子我們可以看出,k近鄰的算法思想非常的簡單,也非常的容易理解,那麼我們是不是就到此結束了,該算法的原理我們也已經懂了,也知道怎麼給新來的點如何進行歸類,只要找到離它最近的k個實例,哪個類別最多即可。

哈哈,沒有這麼簡單啦,算法的核心思想確實是這樣,但是要想一個算法在實際應用中work,需要注意的不少額~比如k怎麼確定的,k爲多少效果最好呢?所謂的最近鄰又是如何來判斷給定呢?哈哈,不要急,下面會一一講解!

二.k近鄰算法中k的選取以及特徵歸一化的重要性 

  1. 選取k值以及它的影響

k近鄰的k值我們應該怎麼選取呢?

如果我們選取較小的k值,那麼就會意味着我們的整體模型會變得複雜,容易發生過擬合!恩~結論說完了,太抽象了吧你,不上圖講解號稱通俗講解的都是流氓~好吧,那我就上圖來講解

假設我們選取k=1這個極端情況,怎麼就使得模型變得複雜,又容易過擬合了呢?

假設我們有訓練數據和待分類點如下圖:

上圖中有倆類,一個是黑色的圓點,一個是藍色的長方形,現在我們的待分類點是紅色的五邊形。

好,根據我們的k近鄰算法步驟來決定待分類點應該歸爲哪一類。我們由圖中可以得到,很容易我們能夠看出來五邊形離黑色的圓點最近,k又等於1,那太好了,我們最終判定待分類點是黑色的圓點。

由這個處理過程我們很容易能夠感覺出問題了,如果k太小了,比如等於1,那麼模型就太複雜了,我們很容易學習到噪聲,也就非常容易判定爲噪聲類別,而在上圖,如果,k大一點,k等於8,把長方形都包括進來,我們很容易得到我們正確的分類應該是藍色的長方形!如下圖:

所謂的過擬合就是在訓練集上準確率非常高,而在測試集上準確率低,經過上例,我們可以得到k太小會導致過擬合很容易將一些噪聲(如上圖離五邊形很近的黑色圓點)學習到模型中,而忽略了數據真實的分佈!

如果我們選取較大的k值,就相當於用較大鄰域中的訓練數據進行預測,這時與輸入實例較遠的(不相似)訓練實例也會對預測起作用,使預測發生錯誤,k值的增大意味着整體模型變得簡單。

k值增大怎麼就意味着模型變得簡單了,不要急,我會解釋的!哈哈。

我們想,如果k=N(N爲訓練樣本的個數),那麼無論輸入實例是什麼,都將簡單地預測它屬於在訓練實例中最多的類。這時,模型是不是非常簡單,這相當於你壓根就沒有訓練模型呀!直接拿訓練數據統計了一下各個數據的類別,找最大的而已!這好像下圖所示:

我們統計了黑色圓形是8個,長方形個數是7個,那麼哈哈,如果k=N,我就得出結論了,紅色五邊形是屬於黑色圓形的(明顯是錯誤的好不,捂臉!

這個時候,模型過於簡單,完全忽略訓練數據實例中的大量有用信息,是不可取的。

恩,k值既不能過大,也不能過小,在我舉的這個例子中,我們k值的選擇,在下圖紅色圓邊界之間這個範圍是最好的,如下圖:


(注:這裏只是爲了更好讓大家理解,真實例子中不可能只有倆維特徵,但是原理是一樣的1,我們就是想找到較好的k值大小)

那麼我們一般怎麼選取呢?李航博士書上講到,我們一般選取一個較小的數值,通常採取 交叉驗證法來選取最優的k值。(也就是說,選取k值很重要的關鍵是實驗調參,類似於神經網絡選取多少層這種,通過調整超參數來得到一個較好的結果

2.距離的度量

在上文中說到,k近鄰算法是在訓練數據集中找到與該實例最鄰近的K個實例,這K個實例的多數屬於某個類,我們就說預測點屬於哪個類。

定義中所說的最鄰近是如何度量呢?我們怎麼知道誰跟測試點最鄰近。這裏就會引出我們幾種度量倆個點之間距離的標準。

我們可以有以下幾種度量方式:

其中當p=2的時候,就是我們最常見的歐式距離,我們也一般都用歐式距離來衡量我們高維空間中倆點的距離。在實際應用中,距離函數的選擇應該根據數據的特性和分析的需要而定,一般選取p=2歐式距離表示,這不是本文的重點。

恩,距離度量我們也瞭解了,下面我要說一下各個維度歸一化的必要性!

3.特徵歸一化的必要性

首先舉例如下,我用一個人身高(cm)與腳碼(尺碼)大小來作爲特徵值,類別爲男性或者女性。我們現在如果有5個訓練樣本,分佈如下:

A [(179,42),男] B [(178,43),男] C [(165,36)女] D [(177,42),男] E [(160,35),女]

通過上述訓練樣本,我們看出問題了嗎?

很容易看到第一維身高特徵是第二維腳碼特徵的4倍左右,那麼在進行距離度量的時候,我們就會偏向於第一維特徵。這樣造成倆個特徵並不是等價重要的,最終可能會導致距離計算錯誤,從而導致預測錯誤。口說無憑,舉例如下:

現在我來了一個測試樣本 F(167,43),讓我們來預測他是男性還是女性,我們採取k=3來預測。

下面我們用歐式距離分別算出F離訓練樣本的歐式距離,然後選取最近的3個,多數類別就是我們最終的結果,計算如下:

由計算可以得到,最近的前三個分別是C,D,E三個樣本,那麼由C,E爲女性,D爲男性,女性多於男性得到我們要預測的結果爲女性

這樣問題就來了,一個女性的腳43碼的可能性,遠遠小於男性腳43碼的可能性,那麼爲什麼算法還是會預測F爲女性呢?那是因爲由於各個特徵量綱的不同,在這裏導致了身高的重要性已經遠遠大於腳碼了,這是不客觀的。所以我們應該讓每個特徵都是同等重要的!這也是我們要歸一化的原因!歸一化公式如下:

講到這裏,k近鄰算法基本內容我們已經講完了。除去之後爲了提高查找效率提出的kd樹外,算法的原理,應用等方面已經講解完畢,由於每篇文章內容不宜太多,kd樹等知識下篇講解,這裏總結一下本文講的內容。

三.本文的一點總結

1.我們提出了k近鄰算法,算法的核心思想是,即是給定一個訓練數據集,對新的輸入實例,在訓練數據集中找到與該實例最鄰近的K個實例,這K個實例的多數屬於某個類,就把該輸入實例分類到這個類中。通俗說一遍算法的過程,來了一個新的輸入實例,我們算出該實例與每一個訓練點的距離(這裏的複雜度爲0(n)比較大,所以引出了下文的kd樹等結構),然後找到前k個,這k個哪個類別數最多,我們就判斷新的輸入實例就是哪類!

2.與該實例最近鄰的k個實例,這個最近鄰的定義是通過不同距離函數來定義,我們最常用的是歐式距離。

3.爲了保證每個特徵同等重要性,我們這裏對每個特徵進行歸一化

4.k值的選取,既不能太大,也不能太小,何值爲最好,需要實驗調整參數確定!

本文講解結束了,真心希望對大家理解有幫助!歡迎大家指錯交流~

參考:

李航博士《統計學習方法》

【量化課堂】一隻兔子幫你理解 kNN

從K近鄰算法、距離度量談到KD樹、SIFT+BBF算法 - 結構之法 算法之道 - 博客頻道 - CSDN.NET

致謝:

德川,繼豪,皓宇,施琦


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