機器學習中KNN是個最基本的分類方法之一。KNN的全稱是K Nearest Neighbor,意思很明顯:求K個最近的樣本。這裏需要說明的有兩點:1、這個近是通過距離來體現的,我們算距離的方法有很多,最常用的有:cos(餘弦距離),曼哈頓(出租車)距離,以及歐幾里得距離。一般來說我們可以使用任何一個求距離的公式去求距離;2、這個距離是求解待分類樣本與已經標記好的已知樣本集中的每個樣本之間的距離。
從上面的分析中,我們可以知道,KNN分類是基於樣本和標籤的分類方法,即每一個樣本必須要有一個明確的標籤。所以我們待分類的樣本通過該方法進行分類之後也必須也會得到唯一的一個標籤與之對應。但是KNN求解的是與待分類樣本距離最近的K個已經標記了的已知樣本。所以我們得到這K個最近鄰的樣本後還必須要對這些樣本進行按照它們所屬的類別進行排序。比如我們的樣本集只有6個樣本,分別是 [A, B, C, D, E, F],對應的標籤分別是[1, 2, 1, 2, 0, 1],待分類樣本是G(其中G和樣本集中的每個樣本的維度應該要一致),通過計算我們發現G與這6個樣本之間的歐式距離分別是[0.147, 0.239, 0.159, 0.289, 1.33, 0.247],K=3,那麼我們會得到如下結果:[0.147, 0.159, 0.239],對應的標籤分別爲:[1, 1, 2]那麼我們發現樣本G可能屬於類別1,也有可能屬於類別2,但是我們發現G屬於類別1的可能性要大些。至於這個可能性一方面是憑直覺,另方面是還是憑直覺([1, 1, 2]),所以我們憑直覺就可以將樣本G歸爲類別1.
下面給出使用python編寫的KNN代碼,這個代碼裏我使用了lambda匿名函數以及python的其它幾個內置函數,不熟悉這些東東的用法的盆友們可以翻看我之前寫的博客。代碼如下:
from math import sqrt def get_data(): data = {'data': [], 'label': []} group = [[1.0, 1.1], [1.0, 1.0], [0, 0], [0, 0.1]] labels = ['A', 'A', 'B', 'B'] data['data'].append(group) data['label'].append(labels) return data def compute_distance(sample, data, k): assert isinstance(sample, list) and len(sample) > 0 assert isinstance(data, dict) and len(data) > 0 assert len(sample) == len(data['data'][0][0]) distance = [0] * len(data['data'][0]) for sample_index in range(0, len(distance), 1): distance[sample_index] = sqrt(sum(list(map(lambda x: pow(x[0] - x[1], 2), zip(data['data'][0][sample_index], sample))))) distance = sorted(zip(distance, data['label'][0]), reverse=False) predicted_label = list(map(lambda x: x[-1], distance[:k])) print(predicted_label) count_labels = sorted(list(map(lambda x: (x, predicted_label.count(x)), set(data['label'][0]))), reverse=True) return count_labels[0][0] label = compute_distance([0, 0], get_data(), 3) print('label:', label)
['A', 'B', 'B'] label: B