1. 程式人生 > >一文搞懂k近鄰(k-NN)演算法(一)

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

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow

也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!

               

原文連結


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

前幾天和德川一起在學習會上講解了k-NN演算法,這裡進行總結一下,力爭用最

通俗的語言講解以便更多同學的理解。


本文目錄如下:

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

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

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

4.kd樹詳細例子講解

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

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


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


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


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



如上圖所示,有兩類不同的樣本資料,分別用藍色的小正方形和紅色的小三角形表示,而圖正中間的那個綠色的圓所標示的資料則是待分類的資料


這也就是我們的目的,來了一個新的資料點,我要得到它的類別是什麼?好的,下面我們根據k近鄰的思想來給綠色圓點進行分類。


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


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

    一類。


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


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


哈哈,不要急,下面會一一講解!


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

選取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值很重要的關鍵是實驗調參,類似於神經網路選取多少層這種,通過調整超引數來得到一個較好的結果


距離的度量


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


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

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



其中當p=2的時候,就是我們最常見的歐式距離,我們也一般都用歐式距離來衡量我們高維空間中倆點的距離。


在實際應用中,距離函式的選擇應該根據資料的特性和分析的需要而定,一般選取p=2歐式距離表示,這不是本文的重點。


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


特徵歸一化的必要性


首先舉例如下,我用一個人身高(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樹等知識下篇講解,這裡總結一下本文講的內容。


3本文的一點總結


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


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


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


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


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


參考:

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

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

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

致謝:

德川,繼豪,皓宇,施琦


推薦閱讀文章:

詳解梯度下降法的三種形式BGD,SGD以及MBGD

淺析感知機(一)--模型與學習策略

《淺析感知機(二)--學習演算法及python程式碼剖析》

《淺析感知機(三)--收斂性證明與對偶形式以及python程式碼講解》


近期文章預告:

《一文搞懂k近鄰(k-NN)演算法(二)》

《詳解貝葉斯分類以及程式碼實現》

《詳解增強學習MDP過程》

《換個角度談線性代數相關基礎》


版權所有,轉載請聯絡作者獲得授權!


開通了[自然語言處理與機器學習]公眾號,記錄自己在cs,ml,nlp中的學習所得,不保證是很難得知識,但一定是我理解的乾貨,歡迎按住下面二維碼掃描關注!



           

給我老師的人工智慧教程打call!http://blog.csdn.net/jiangjunshow

這裡寫圖片描述 你好! 這是你第一次使用 **Markdown編輯器** 所展示的歡迎頁。如果你想學習如何使用Markdown編輯器, 可以仔細閱讀這篇文章,瞭解一下Markdown的基本語法知識。

新的改變

我們對Markdown編輯器進行了一些功能拓展與語法支援,除了標準的Markdown編輯器功能,我們增加了如下幾點新功能,幫助你用它寫部落格:

  1. 全新的介面設計 ,將會帶來全新的寫作體驗;
  2. 在創作中心設定你喜愛的程式碼高亮樣式,Markdown 將程式碼片顯示選擇的高亮樣式 進行展示;
  3. 增加了 圖片拖拽 功能,你可以將本地的圖片直接拖拽到編輯區域直接展示;
  4. 全新的 KaTeX數學公式 語法;
  5. 增加了支援甘特圖的mermaid語法1 功能;
  6. 增加了 多螢幕編輯 Markdown文章功能;
  7. 增加了 焦點寫作模式、預覽模式、簡潔寫作模式、左右區域同步滾輪設定 等功能,功能按鈕位於編輯區域與預覽區域中間;
  8. 增加了 檢查列表 功能。

功能快捷鍵

撤銷:Ctrl/Command + Z
重做:Ctrl/Command + Y
加粗:Ctrl/Command + B
斜體:Ctrl/Command + I
標題:Ctrl/Command + Shift + H
無序列表:Ctrl/Command + Shift + U
有序列表:Ctrl/Command + Shift + O
檢查列表:Ctrl/Command + Shift + C
插入程式碼:Ctrl/Command + Shift + K
插入連結:Ctrl/Command + Shift + L
插入圖片:Ctrl/Command + Shift + G

合理的建立標題,有助於目錄的生成

直接輸入1次#,並按下space後,將生成1級標題。
輸入2次#,並按下space後,將生成2級標題。
以此類推,我們支援6級標題。有助於使用TOC語法後生成一個完美的目錄。

如何改變文字的樣式

強調文字 強調文字

加粗文字 加粗文字

標記文字

刪除文字

引用文字

H2O is是液體。

210 運算結果是 1024.

插入連結與圖片

連結: link.

圖片: Alt

帶尺寸的圖片: Alt

當然,我們為了讓使用者更加便捷,我們增加了圖片拖拽功能。

如何插入一段漂亮的程式碼片

部落格設定頁面,選擇一款你喜歡的程式碼片高亮樣式,下面展示同樣高亮的 程式碼片.

// An highlighted block var foo = 'bar'; 

生成一個適合你的列表

  • 專案
    • 專案
      • 專案
  1. 專案1
  2. 專案2
  3. 專案3
  • 計劃任務
  • 完成任務

建立一個表格

一個簡單的表格是這麼建立的:

專案 Value
電腦 $1600
手機 $12
導管 $1

設定內容居中、居左、居右

使用:---------:居中
使用:----------居左
使用----------:居右

第一列 第二列 第三列
第一列文字居中 第二列文字居右 第三列文字居左

SmartyPants

SmartyPants將ASCII標點字元轉換為“智慧”印刷標點HTML實體。例如:

TYPE ASCII HTML
Single backticks 'Isn't this fun?' ‘Isn’t this fun?’
Quotes "Isn't this fun?" “Isn’t this fun?”
Dashes -- is en-dash, --- is em-dash – is en-dash, — is em-dash

建立一個自定義列表

Markdown
Text-to- HTML conversion tool
Authors
John
Luke

如何建立一個註腳

一個具有註腳的文字。2

註釋也是必不可少的

Markdown將文字轉換為 HTML

KaTeX數學公式

您可以使用渲染LaTeX數學表示式 KaTeX:

Gamma公式展示 Γ ( n ) = ( n 1 ) ! n N \Gamma(n) = (n-1)!\quad\forall n\in\mathbb N 是通過尤拉積分

Γ ( z ) = 0 t z 1 e t d t   . \Gamma(z) = \int_0^\infty t^{z-1}e^{-t}dt\,.

你可以找到更多關於的資訊 LaTeX 數學表示式here.

新的甘特圖功能,豐富你的文章

gantt
        dateFormat  YYYY-MM-DD
        title Adding GANTT diagram functionality to mermaid
        section 現有任務
        已完成               :done,    des1, 2014-01-06,2014-01-08
        進行中               :active,  des2, 2014-01-09, 3d
        計劃一               :         des3, after des2, 5d
        計劃二               :         des4, after des3, 5d
  • 關於 甘特圖 語法,參考 這兒,

UML 圖表

可以使用UML圖表進行渲染。 Mermaid. 例如下面產生的一個序列圖::

這將產生一個流程圖。:

  • 關於 Mermaid 語法,參考 這兒,

FLowchart流程圖

我們依舊會支援flowchart的流程圖:

  • 關於 Flowchart流程圖 語法,參考 這兒.

匯出與匯入

匯出

如果你想嘗試使用此編輯器, 你可以在此篇文章任意編輯。當你完成了一篇文章的寫作, 在上方工具欄找到 文章匯出 ,生成一個.md檔案或者.html檔案進行本地儲存。

匯入

如果你想載入一篇你寫過的.md檔案或者.html檔案,在上方工具欄可以選擇匯入功能進行對應副檔名的檔案匯入,
繼續你的創作。


  1. mermaid語法說明 ↩︎

  2. 註腳的解釋 ↩︎