先看一个实例来体会一下什么叫做KNN。已知一堆数据a和一堆数据0,然后有一个未知数据c,要判断c到底属于a还是0.如果是1NN,就找到离C最近的数据,离哪一个最近,就判断c属于哪一类。如果利用3NN,如下图所示,以c为半径画圆,直到找出三个数为止,分别有一个a,两个0,则说明c属于0.(注意K一定是奇数可以保证不会平票)
接下来通过一个实例来讲一下KNN
分类问题:
一个学生是不是三好学生通过德智体三个方面来进行评价。如果我们的样本空间如下:(所谓样本空间,又叫Training Data,也就是用于机器学习的数据)
学生编号 | 向量1 | 向量2 | 向量3 | 是否为三好学生 |
赵1 | 9 | 8 | 9 | 是 |
钱2 | 8 | 7 | 8 | 是 |
孙3 | 4 | 6 | 7 | 不是 |
李4 | 3 | 5 | 9 | 不是 |
周5 | 9 | 3 | 9 | 是 |
吴6 | 2 | 9 | 7 | ? |
那么吴6是三好学生不是呢?我们使用KNN算法来判断。假设K=3,K应该是一个奇数,这样可以保证不会有平票,下面是我们计算(2,9,7)到所有点的距离。(距离公式,可以参看K-Means算法中的一些距离定义)
学生编号 | 向量1 | 向量2 | 向量3 | 到吴六的距离 | 是否为三好学生 |
赵一 | 9 | 8 | 9 | ![]() ![]() | 是 |
钱二 | 8 | 7 | 8 | ![]() | 是 |
孙三 | 4 | 6 | 7 | 不是 | |
李四 | 3 | 5 | 9 | ![]() | 不是 |
周五 | 9 | 3 | 9 | ![]() | 是 |
离吴六最近的几个人是孙三,李四,钱二,只有钱儿是三好学生,孙三和李四都不是,那么吴六也不是三好学生了,这样就可以把吴六分类为不是三好学生。
当然利用kNN也可以解决回归问题,但是最大最有效的就是分类问题了。2)对于KNN算法中找到离自己最近的K个点需要使用到最大堆数据结构。也会做出阐述。
接下来先通过一个实例来使用KNN对MNIST最经典的字符识别做一下分类实验。
代码如下:
程序说明:1.因为使用的为one_hot编码,故Ytr为n*10的数组,每个数组形式都为【九个0+一个1】的形式,找到Ytr【nn_index】后只需要使用np.argmax()函数找到1所在位置即为数字。
补充:关于placeholder与reduce_sum的一些问题
说明:
reduce_sum() 就是求和,由于求和的对象是tensor,所以是沿着tensor的某些维度求和。函数名中加了reduce是表示求和后会降维,当然可以通过设置参数来保证不降维,但是默认就是要降维的。
参数解释:
1)input_tensor:输入的张量。
2)axis:沿着哪个维度求和。
对于二维的input_tensor张量,0表示按列求和,1表示按行求和,[0, 1]表示先按列求和再按行求和。
3)keep_dims:默认值为Flase,表示默认要降维。若设为True,则不降维。
4)name:名字。
5)reduction_indices:默认值是None,即把input_tensor降到 0维,也就是一个数。
对于2维input_tensor,reduction_indices=0时,按列;reduction_indices=1时,按行。
注意,reduction_indices与axis不能同时设置。
其中当shape为三维矢量,比如[2,2,3]
后两维表示矩阵为[2,3]格式的,分为两层
那么数据格式是这样的。运用在reduce_sum中,如果axis=0,则第一维求和。即上下数分别对应求和。如果axis=1,则第二维求和,即第一行+第二行,求出结果是一行三列。axis=2.则第三维求和,即第一列+第二列+第三列。结果是两行一列