連載|機器學習|通俗易懂的KNN

K近鄰(KNN)算法

之前一段時間我們瞭解到的算法中,可以說是一個比一個複雜,本文呢,我們不再增加難度,來說一個最基礎、最簡單的監督學習算法KNN。

KNN的原理

我們給定一個數據集,對於一個新來的樣本,我們在數據集中找到距離該樣本最近的K個樣本,在這K個樣本中,某一類出現的次數最多我們就把這個樣本分到這個類別中。

舉一個例子:

在這裏插入圖片描述

如圖所示,紅色的三角和藍色的方塊爲我們原有的數據集,綠色的圓即爲一個新來到的樣本,事先我們並不知道它屬於某一類,我們來嘗試兩種不同的K值下的分類方法:

K=3
當我們選取K=3時,很明顯距離綠色圓最近的三個樣本爲兩個紅色三角和一個藍色方塊,按照KNN的分類原則我們就可以將綠色圓分爲紅色三角一類。

K=5
當我們選取K=5時,很明顯距離綠色圓最近的五個樣本爲兩個紅色三角和一個藍色方塊,同理我們就可以將綠色園分爲藍色方塊一類。

也就是這樣

K值的選取 藍色方塊個數 紅色三角個數 綠色圓分類
K=3 ▲▲
K=5 ■■■ ▲▲

根據這個例子我們就能總結出KNN算法的基本步驟:

(1)計算數據集中每個點到測試數據的距離d(i);

(2)將算得的距離d(i)進行從小到大的排序;

(3)根據我們設定的K值選取排序後的前K個點;

(4)確定選取到的K個點中每一類別出現的頻率;

(5)將出現頻率最高的一類作爲測試樣本的預測分類結果。

從這個簡單的例子可以看出,當我們選取不同的K值時會有不同的結果,那我們應該如何去選擇K值,又應該如何去計算數據集中每個樣本到新樣本之間的距離呢?下面會給出解答。

KNN距離的度量

在我們數學的學習中關於度量的方式有很多種,我門在瞭解KNN所需要的距離度量方式的同時,也來了解一下其它的距離度量方式。

閔可夫斯基距離

閔可夫斯基距離是衡量數值點之間距離的一種非常常見的方法,假設數值點P和Q座標如下:

P=(x1,x2,x3,...,xn)P=(x_1,x_2,x_3,...,x_n)

Q=(y1,y2,y3,...,yn)Q=(y_1,y_2,y_3,...,y_n)

那麼閔可夫斯基距離的定義爲:

d(x,y)=(i=1nxiyip)1pd(x,y)=(\sum_{i=1}^n|x_i-y_i|^p)^\frac{1}{p}

歐式距離

對於閔可夫斯基距離,當p=2時,我們稱之爲歐式距離(歐幾里得距離)。

d(x,y)=k=1n(xkyk)2d(x,y)=\sqrt{\sum_{k=1}^{n}(x_k-y_k)^2 }

曼哈頓距離

對於閔可夫斯基距離,當p=1時,我們稱之爲曼哈頓距離。

d(x,y)=k=1nxkykd(x,y)={\sum_{k=1}^{n}\left | x_k-y_k \right | }

切比雪夫距離

對於閔可夫斯基距離,當P趨近於無窮大時,可以轉化爲切比雪夫距離。

(limi=1nxiyip)1p=maxi=1nxiyi(\underset{\infty}{\lim}\sum_{i=1}^n|x_i-y_i|^p)^\frac{1}{p}=max_{i=1}^{n}|x_i-y_i|

和之前說到過的k-means算法一樣,我們在KNN中也要使用歐式距離來進行距離的度量。

K值的選擇

不同K值出現的問題

KNN中如何進行K值的選擇是一個讓人頭大的問題,選的大了小了都會出現一定的問題,我們先來看一下下面的例子產生的問題:

在這裏插入圖片描述

和我們在講第一個例子的時候同理,同樣是將綠色圓作爲測試樣本,我們分別取K=1,K=7,K=N進行訓練。

K值的選取 藍色方塊個數 紅色三角個數 綠色圓的分類
K=1 None
K=7 ▲▲▲▲▲▲
K=N ■■■■■■■ ▲▲▲▲▲▲

很顯然當K=1的時候,我們使用了一個複雜的模型,該模型下我們很容易的學習到了訓練樣本中的噪聲,從而導致了模型過擬合現象的出現;將K值增大,當K=7時,可以看出我們得到了一個相對正確的分類;再繼續增大K值爲N(訓練集所有樣本的個數),這種做法會導致我們將模型設計的過於簡單,從而導致預測結果發生錯誤,由此可見選擇一個合適的K值是多麼的重要。

如果選擇較小的K值,就相當於用較小的領域中的訓練實例進行預測,“學習”近似誤差會減小,只有與輸入實例較近或相似的訓練實例纔會對預測結果起作用,與此同時帶來的問題是“學習”的估計誤差會增大,換句話說,K值的減小就意味着整體模型變得複雜,容易發生過擬合;

如果選擇較大的K值,就相當於用較大領域中的訓練實例進行預測,其優點是可以減少學習的估計誤差,但缺點是學習的近似誤差會增大。這時候,與輸入實例較遠(不相似的)訓練實例也會對預測器作用,使預測發生錯誤,且K值的增大就意味着整體的模型變得簡單。

K=N,此時無論輸入實例是什麼,都只是簡單的預測它屬於在訓練實例中最多的類,模型過於簡單,忽略了訓練實例中大量有用信息。

在實際應用中,K值一般取一個比較小的數值,例如採用交叉驗證法(簡單來說,就是一部分樣本做訓練集,一部分做測試集)來選擇最優的K值。

交叉驗證選擇K值

在進行K值選擇的時候,我們通過經驗去找當然是沒有問題的,但是對於沒有經驗的人來說,可以使用交叉驗證的方法去找到一個最佳的K值,簡單的說交叉驗證法就是把我們的數據分爲n份,每次拿出其中的1份當作測試集,其它的當作訓練集來進行n次訓練,最終對這n次訓練的得分進行平均。我們選擇K值的做法就是給定一段K的範圍,在這個範圍內對於每一個K值都進行一次交叉驗證,最終我們在K值取的比較小的條件下去選擇得分最高的的就可以了。下面給出一段代碼實現:

from __future__ import print_function
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
x = iris.data
y = iris.target
k_range = range(1, 31)
k_score = []
for k in k_range:
    # n_neighbors:KNN算法中K的取值
    knn = KNeighborsClassifier(n_neighbors=k)
    # cv:選擇每次測試折數  accuracy:評價指標是準確度,可以省略使用默認值
    score = cross_val_score(knn, x, y, cv=10, scoring='accuracy')
    k_score.append(score.mean())

plt.plot(k_range, k_score)
plt.xlabel("Value of k for KNN")
plt.ylabel("accuracy")
plt.show()

在這裏插入圖片描述

從圖像中我們就可以看出,當K取13的時候就能達到一個很高的得分了,此時我們選擇K=13就可以了。

KD樹

KD樹是一種對K維空間中的實例點進行存儲以便對其進行快速檢索的樹形結構。KD樹是二叉樹,表示對K維空間進行劃分,構造KD樹相當於不斷地用垂直於座標軸的超平面將K維空間劃分,構成一些列的K維超矩形區域,KD樹的每個節點對應於一個K維超矩形區域。

KD樹的構建過程舉例

給定二維空間的數據集:T={(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)},構建一個KD樹。

  • (1)找到劃分的特徵。6個數據點在x,y維度上的數據方差分別爲6.97,5.37,所以X軸上方差更大,用第一維特徵建樹。
  • (2)確定劃分點(7,2)。根據X維上的值將數據排序,6個數據的中值(奇數個數據的時候爲中值,偶數個數據的時候爲中值向下取存在的整數)爲7,所以劃分點的數據是(7,2),此時節點的分割超平面就是通過該點並且垂直於X軸,即:直線X=7。
  • (3)確定左子空間和右子空間。直線X=7將空間劃分爲左右:左子空間[(2,3),(5,4),(4,7)],右子空間[(9,6),(8,1)]。
  • (4)重複上述方法繼續劃分,直到不能劃分爲止,得到KD樹。

最終得到的KD樹的結果如下:

在這裏插入圖片描述

特徵空間的劃分如下:

在這裏插入圖片描述

我們構建KD樹的目的是爲了使用KD樹進行最近鄰搜索,搜索的過程如下:

  1. 在KD樹中找出包含目標點x的葉結點:從根結點出發,遞歸地向下訪問kd樹。若目標點x當前維度的座標小於且分點的座標,則移動到左子結點,否則移動到右子結點。直到子結點爲葉子結點爲止。
  2. 以此葉結點爲“當前最近點”。
  3. 遞歸地向上回退,在每個結點進行以下操作:
  • 如果該結點保存的實例點比當前最近點距離目標點更近,則以該實例點爲“當前最近點”。
  • 當前最近點一定存在於該結點的一個子結點的對應區域,檢查該子結點的父結點的另一子結點對應的區域是否有更近的點。具體的,檢查另一子結點對應的區域是否與目標點爲球心,以目標點與“當前最近點”間的距離爲半徑的球體相交。
  • 如果相交,可能在另一個子結點對應的區域內存在距目標點更近的點,移動到另一個子結點。接着遞歸進行最近鄰搜索。
  • 如果不相交,向上回退。
  1. 當回退到根結點時,搜索結束。最後的“當前最近點”即爲x的最近鄰點。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章