在讲解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