【CS231n】KNN浅谈 + KNN代码实现

本文介绍了KNN(K最近邻)算法的基本原理,包括Nearest Neighbor的概念和KNN的优势。讨论了如何度量相似性,如L1和L2距离,并提供了使用numpy进行数据处理的技巧。同时,详述了KNN的Python代码实现,包括数据加载、可视化、KNN分类器的训练和优化,以及选择最佳K值的过程。
摘要由CSDN通过智能技术生成

简要介绍KNN(K Nearest Neighbor)

Nearest Neighbor

     介绍KNN以前,我们先了解一下Nearest Neighbor。Nearest Neighbor主要用于分类,以CIFAR-10数据集为例,有50000张训练图片和与之对应的标签。我们将要为测试集标上标签,我们取一张测试集中的图片,在训练集中找出与之最相似的一张图片,那么该测试集图片与该最相似的一张的图片的标签相同。但是这样也有局限性。

KNN算法的决策过程

    以改图为例,我们现在要对绿色圆形进行分类,看起来绿色圆形仿佛应该属于红色三角形,但是事实可能往往并不是这样,所以便有了KNN。

K Nearest Neighbor

       如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

    KNN算法比NN算法误差要小一些,因为KNN中的K我们可以通过在训练集找到一个比较好的K,在测试集上KNN的误差比NN的误差要小。

 

KNN算法的决策过程

  还是以此图为例,如果用NN算法,绿色圆形本应属于红色三角形,当K=3时,也是如此。但是当K=5时,绿色圆形属于蓝色三角性,可见,绿色圆点到底属于哪一类,与具体的K有关。所以我们要看分类的对象,并训练KNN分类器,毕竟如果NN算法要好的话,也是KNN算法中K=1的特殊情况。

也就是说:K Nearest Neighbor 算法包含了 Nearest Neighbor算法

如何度量相似

  L1(Manhattan)distance

   

L2 distance

 

 

numpy技巧

idxs = np.flatnonzero(): 返回非0元素的位置

idxs = np.random.choice():从数组中随机抽取元素

plt.subplot():子图绘制

np.linalg.norm():计算范数

np.array_split():数组划分

np.vstack(): 按垂直方向(行顺序)堆叠数组构成一个新的数组

np.hstack(): 按水平方向(列顺序)堆叠数组构成一个新的数组

np.argsort():排序,返回索引值

np.bincount():返回每个索引出现的次数

 

KNN代码实现

github:https://github.com/GIGpanda/CS231n

一共两个.py文件,knn.py和k_nearest_neighbor.py

knn.py

数据加载

加载CIFAR-10数据,并打印训练集和测试集的图片、标签尺寸。

# KNN

from __future__ import print_function
import random
import numpy as np
from cs231n.data_utils import load_CIFAR10
import matplotlib.pyplot as plt
from cs231n.classifiers import KNearestNeighbor
import time

plt.rcParams['figure.figsize'] = (10.0, 8.0) # set default size of plots
plt.rcParams['image.interpolation'] = 'nearest'
plt.rcParams['image.cmap'] = 'gray'

# Load the raw CIFAR-10 data.
cifar10_dir = 'cs231n/datasets/cifar-10-batches-py'
X_train, y_train, X_test, y_test = load_CIFAR10(cifar10_dir)

# As a sanity check, we print out the size of the training and test data.
print('Training data shape: ', X_train.shape)
print('Training labels shape: ', y_train.shape)
print('Test data shape: ', X_test.shape)
print('Test labels shape: ', y_test.shape)

可视化部分数据

 对于训练集中的10类数据,每类随机取出7张并可视化。

# Visualize some examples from the dataset.
# We show a few examples of training images from each class.
classes = ['plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']
num_classes = len(classes)
samples_per_class = 7
for y, cls in enumerate(classes):
    idxs = np.flatnonzero(y_train == y)    # np.flatnonzero 返回非0元素的位置
    idxs = np.random.choice(idxs, samples_per_class, replace=False)
    # np.random.choice 从数组中随机抽取元素
    # 从数组idxs中随机抽取数字, 组成大小为samples_per_class的数组, replace=False表示不可以取相同的数字
    for i, idx in enumerate(idxs):
        plt_idx = i * num_classes + y + 1
        # plt_idx 算出每张图片打印出来的位置 也就是同一类图片在同一列
        plt.subplot(samples_per_class, num_classes, plt_idx)
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值