在講解K近鄰分類器以前,咱們先來看一下最近鄰分類器(Nearest Neighbor Classifier),它也是K = 1時的K近鄰分類器。
html
最近鄰分類器是在最小距離分類的基礎上進行擴展的,將訓練集中的每個樣本做爲判斷依據,尋找距離待分類樣本中最近的訓練集中的樣本,以此依據進行分類。java
如上圖所示,咱們的訓練集表明了二維平面上的點,而不一樣的顏色表明了不一樣的類別(標籤).python
噪聲
(圖像噪聲是指存在於圖像數據中的沒必要要的或多餘的干擾信息。)咱們從上面的圖中能夠看出,綠色的區域內還有一個黃色區域,此時這個區域應該是綠色,由於黃色的點頗有多是噪聲,但咱們使用最近鄰算法就有可能出現上面的問題。git
與最近鄰分類器類不一樣的是,k近鄰分類器是幾個測試的樣本共同抉擇屬於哪個樣本,以下所示,當k = 1(也就是最近鄰分類器),3,5時的分類器抉擇結果。github
爲了幫助你們更好地理解,咱們引入下面一個示例:
k近鄰算法例子。測試樣本(綠色圓形)應納入要麼是第一類的藍色方形或是第二類的紅色三角形。若是k=3(實線圓圈)它被分配給第二類,由於有2個三角形和只有1個正方形在內側圓圈以內。若是k=5(虛線圓圈)它被分配到第一類(3個正方形與2個三角形在外側圓圈以內)。算法
如今有一個問題,那就是咱們如何比較相對近鄰距離值,下面給出兩種方法app
對於這兩種方法,你們能夠參考下面的博文:歐氏距離,曼哈頓距離,餘弦距離,漢明距離測試
L1距離:它上面的點的橫座標的絕對值與縱座標的絕對值之和老是相等,也就是到原點在座標軸度量上是相等的。
L2距離:它上面的每個點的座標到原點的距離都相等。.net
你們有興趣的能夠在斯坦福大學的實驗平臺上調試數據進行試驗
附:cs231n-demo實驗調試
咱們經過試驗,能夠找出最優值k。固然,在CS231n當中,咱們也看到了一種新的方法,在有限數據集的狀況之下進行的實驗:K折交叉驗證
從實驗的結果,大約在k = 7時,咱們能獲得最優的解。
(1)Distance Matrix
咱們假定使用L1距離,則計算過程以下:
可是計算標尺與鄰近特定距離標尺之間的關係並不會給咱們帶來什麼太有用的訊,以下,
Boxed,Shifted,Tinted與Original不一樣,可是 K-Nearest Neighbor 結果出來的確實同樣的。
(2)計算時間過長。
import pickle import os import numpy as np n = 2 def unpickle_as_array(filename): with open(filename, 'rb') as f: dic = pickle.load(f, encoding='latin1') dic_data = dic['data'] dic_labels = dic['labels'] dic_data = np.array(dic_data).astype('int') dic_labels = np.array(dic_labels).astype('int') return dic_data, dic_labels def load_batches(root, n): train_data = [] train_labels = [] for i in range(1, n + 1, 1): f = os.path.join(root, 'data_batch_%d' % i) data, labels = unpickle_as_array(f) train_data.append(data) train_labels.append(labels) train_data_r = np.concatenate(train_data) train_labels_r = np.concatenate(train_labels) del train_data, train_labels test_data, test_labels = unpickle_as_array(os.path.join(root, 'test_batch')) return train_data_r, train_labels_r, test_data, test_labels def knn_classification(train_d, test_d, train_l, k): count = 0 result = np.zeros(10000) for i in range(10000): d_value = test_d[i] - train_d distance = np.sum(np.abs(d_value), axis=1) dis_sort = np.argsort(distance) vote_label = np.zeros(10) for j in range(k): vote_label[train_l[dis_sort[j]]] += 1 result[i] = np.argmax(vote_label) print('the %dth image\'s label: %d' % (count, result[i])) count = count + 1 return result train_data, train_labels, test_data, test_labels = load_batches('D:/data/cifar-10-python/cifar-10-batches-py', n) result = knn_classification(train_data, test_data, train_labels, 3) print('the algorithm\'s accuracy: %f' % (np.mean(result == test_labels)))
CIFAR的下載:https://www.cs.toronto.edu/~kriz/cifar.html
你們進入官網後,能夠選擇CIFAR-10 python進行下載,而後修改
train_data, train_labels, test_data, test_labels = load_batches('D:/data/cifar-10-python/cifar-10-batches-py', n)
中的路徑。
你們也能夠參考個人GitHub:-cifar-10-KNN