KNN 算法的思想
KNN(K Neareast Neighbours) 又稱 K 鄰近算法,是一種直觀明了的算法,可以理解為“近朱者赤近墨者黑”。
你也許聽過一句話“一個人的收入是身邊交往最多的五個人的收入的平均值”,這就是“密友五次理論”,這個理論恰好就體現(xiàn)了 KNN 算法的思想。

以上圖為例,假設有兩種數(shù)據(jù),紅色五角星和藍色三角形,現(xiàn)在我們不知道綠色方塊是屬于哪一類,我們該怎么判斷呢?
如果我們用 KNN 算法的思想來判斷,找到綠色方塊最近的幾個鄰居,根據(jù)最近幾個鄰居的來推測綠色方塊是屬于哪一類。
假設 K = 5,距離綠色方塊最近的 5 個鄰居是 3 藍 + 2 紅;
假設 K = 10,距離綠色方塊最近的 10 個鄰居是 6 紅 + 4藍
由上面的步驟中還有 2 個問題需要確定:
1. 怎么計算距離
兩個樣本間的距離代表了樣本之間的相似度,距離越大差異性越大;距離越小相似性越高。 KNN 中常用的距離計算方式有
-
歐氏距離
歐氏距離是我們最常用的距離公式,在 n 維空間中的歐式距離可以表示為:
-
曼哈頓距離
曼哈頓距離等于兩個點在坐標系上絕對軸距總和:
2. 怎么判定類別
- 少數(shù)服從多數(shù),取 K 個樣本中類別最多的為預測類別
- 加權法,依據(jù)離預測樣本的距離遠近設定權值,越近的權重越大
解決了這兩個問題后我們來梳理一下 KNN 算法的流程,KNN 模型的建立過程大概有這幾部:
- 給定測試樣本,計算它與訓練集中每一個樣本的距離
- 找出距離最近的 K 個樣本,作為測試樣本的鄰近
- 依據(jù)這 K 個鄰近樣本的類別來預測樣本的類別
K 值的選擇
那么問題來了,怎么選擇 K 值呢? K 值的大小直接影響了 KNN 的預測結果。 如果 K 值過小,如果鄰近點是噪聲點,那這個噪聲的影響會過大,這樣會產生過擬合; 如果 K 值過大,那么距離較遠的樣本也會對預測結果造成影響,雖然這樣能減小誤差,但是也會讓整個模型變得簡單,產生欠擬合的情況。 在實際應用中,一般采用交叉驗證的方式選擇 K 值,選擇在較小的范圍,同時在驗證集上準確率最高的最終確定為 K 值。
動手練習
用 KNN 算法來進行手寫數(shù)字分類,使用的是sklearn中自帶的數(shù)據(jù)集。
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_digits
from sklearn.metrics import accuracy_score
from sklearn import preprocessing
import matplotlib.pyplot as plt
# 加載數(shù)據(jù)
digits = load_digits()
data = digits.data
print(data.shape)
# 查看第一個數(shù)字圖像
print(digits.target[0])
plt.gray()
plt.imshow(digits.images[0])
plt.show()

分割數(shù)據(jù)為訓練集和測試集,由于要進行距離計算,而且我們只關心數(shù)字的形狀,所以先將圖像數(shù)據(jù)進行Z-Score規(guī)范化會更好:
train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size = 0.2, random_state = 2020)
# Z-Score
scaler = preprocessing.StandardScaler()
train_scaled_x = scaler.fit_transform(train_x)
test_scaled_x = scaler.transform(test_x)
用 KNN 模型進行訓練和預測:
knn = KNeighborsClassifier()
knn.fit(train_scaled_x, train_y)
pred_y = knn.predict(test_scaled_x)
print("knn accuracy: %.4f" % accuracy_score(test_y, pred_y))
最后預測準確度為 0.9861 KNN 模型雖然簡單,但有時效果還是不錯的~~
總結一下 KNN 算法的優(yōu)缺點:
-
優(yōu)點:
- 模型簡單,易于理解、易于實現(xiàn)、無需估計參數(shù)
- 適合對稀有事件進行分類
- 特別適合多分類問題
-
缺點:
- 對測試樣本分類時的計算量大,內存開銷大,評分慢
- 可解釋性差,無法給出決策樹那樣的規(guī)則
- 當樣本不平衡時,在選取 K 個鄰居時容易造成大容量樣本占多數(shù)的情況,影響分類結果
- 沒有提前訓練過程,直到要分類預測時才對進行,這是一種消極學習法
END