knn 分类器_knn分类器 - CSDN
  • 图像分类基本流程及 KNN 分类器

    千次阅读 2018-09-07 16:14:06
      所谓图像分类问题,就是已有固定的分类标签集合,然后对于输入的图像,从分类标签集合中找出一个分类标签,最后把分类标签分配给该输入图像。虽然看起来挺简单的,但这可是计算机视觉领域的核心问题之一,计算机...

    1. 图像分类以及基本流程

    1.1 什么是图像分类

      所谓图像分类问题,就是已有固定的分类标签集合,然后对于输入的图像,从分类标签集合中找出一个分类标签,最后把分类标签分配给该输入图像。虽然看起来挺简单的,但这可是计算机视觉领域的核心问题之一,计算机视觉领域中很多看似不同的问题(比如物体检测和分割),都可以被归结为图像分类问题。

    1.2 图像分类的挑战

      物体分类与检测的难点与挑战在本文中分为3个层次:实例层次、类别 层次和语义层次,如图 1 所示 [1] 


    图 1 .物体分类与检测研究存在的困难与挑战

     

      (1) 实例层次。针对单个物体实例而言,通常于图像采集过程中、光照条件拍摄视角距离的不同而造成的尺寸变化、物体自身的非刚体形变以及其他物体的部分遮挡,使得物体实例的表观特征产生很大的变化,给视觉识别算法带来了极大的困难

      (2) 类别层次。困难与挑战通常来自3个方面,首先是类内差大,也即属于同一类的物体表观特征差别比较大,其原因有前面提到的各种实例层次的变化,但这里更强调的是类内不同实例的差别,例如图2 (a) 所示,同样是椅子,外观却是千差万别,而从语义上来讲,具有“坐”的功能的器具都可以称为椅子;其次是类间模糊性,即不同类的物体实例具有一定的相似性,如图2 (b)所示,左边的是一只狼,右边的是一只哈士奇,但我们从外观上却很难分开二者;再次是背景的干扰,在实际场景下,物体不可能出现在一个非常干净的背景下,往往相反,背景可能是非常复杂的、对我们感兴趣的物体存在干扰的,这使得识别问题的难度大大增加。

      (3) 语义层次。困难和挑战与图像的视觉语义相关,这个层次的困难往往非常难处理,特别是对现在的计算机视觉理论水平而言,一个典型的问题称为多重稳定性。如图3所示,图3(c) 左边既可以看成是两个面对面的人,也可以看成是一个燃烧的蜡烛;右边则同时可以解释为兔子或者小鸭。同样的图像,不同的解释,这既与人的观察视角、关注点等物理条件有关,也与人的性格、经历等有关,而这恰恰是视觉识别系统难以处理的部分。

     


    图 2 .分类与检测存在挑战的例子

     

    1.3 图像分类的基本流程

      在机器学习中常常采用基于数据驱动的方法进行图像分类。所谓基于数据驱动的方法,就是给计算机很多数据,然后实现学习算法,让计算机学习到每个类的外形的方法。基于这种方法的完整流程如下

      (1) 输入:输入是包含 N 个图像的集合,每个图像的标签是 K 种分类标签中的一种。这个集合称为训练集。

      (2) 学习:这一步的任务是使用训练集来学习每个类到底长什么样。一般该步骤叫做训练分类器或者学习一个模型。

      (3) 评价:让分类器来预测它未曾见过的图像的分类标签,并以此来评价分类器的质量。我们会把分类器预测的标签和图像真正的分类标签对比。毫无疑问,分类器预测的分类标签和图像真正的分类标签如果一致,那就是好事,这样的情况越多越好。

    2. K - Nearest Neighbor分类器

    2.1 Nearest Neighbor分类器

      它的原理是拿着测试图片和训练集中每一张图片去比较,然后将它认为最相似的那个训练集图片的标签赋给这张测试图片。在 CIFAR­10 中,就是比较 32x32x3 的像素块。最简单的方法就是逐个像素比较,最后将差异值全部加起来。换句话说,就是将两张图片先转化为两个向量 和 ,然后计算他们的 L1 距离: 

    d1(I1,I2)=∑p|Ip1−Ip2|d1(I1,I2)=∑p|I1p−I2p|


    作为评价标准,我们常常使用准确率.。同样也有很多的其他评价标准,我们将在日后的学习笔记中逐渐补充

     

      距离选择:计算向量间的距离有很多种方法,另一个常用的方法是 L2 距离,从几何学的角度,可以理解为它在计算两个向量间的欧式距离。L2 距离的公式如下: 

    d2(I1,I2)=∑p(Ip1−Ip2)2−−−−−−−−−−−√d2(I1,I2)=∑p(I1p−I2p)2


    换句话说,我们依旧是在计算像素间的差值,只是先求其平方,然后把这些平方全部加起来,最后对这个和开方。注意这里使用了开平方,但是在实际中可能不用。因为求平方根函数是一个单调函数,它对不同距离的绝对值求平方根虽然改变了数值大小,但依然保持了不同距离大小的顺序。所以用不用它,都能够对像素差异的大小进行正确比较。

     

      L1 和 L2 比较。比较这两个度量方式是挺有意思的。在面对两个向量之间的差异时,L2 比 L1 更加不能容忍这些差异。也就是说,相对于1个巨大的差异,L2 距离更倾向于接受多个中等程度的差异。L1 和 L2 都是在 p-­norm 常用的特殊形式。更多的衡量距离的标准将在之后的笔记中进行讨论。

    2.2 K-Nearest Neighbor分类器

      它的思想很简单:与其只找最相近的那 1 个图片的标签,我们找最相似的 k 个图片的标签,然后让他们针对测试图片进行投票,最后把票数最高的标签作为对测试图片的预测。所以当 k=1 的时候,k­Nearest Neighbor 分类器就是 Nearest Neighbor 分类器。从图 3 直观感受上就可以看到,更高的 k 值可以让分类的效果更平滑,使得分类器对于异常值更有抵抗力。 


    图 3 .NN与KNN的对比结果

     

    需要注意的是,在 NN 分类器中,异常的数据点(比如:在蓝色区域中的绿点)制造出一个不正确预测的孤岛。5­NN 分类器将这些不规则都平滑了,使得它针对测试数据的泛化(generalization)能力更好(例子中未展示)。注意,5­NN 中也存在一些灰色区域,这些区域是因为近邻标签的最高票数相同导致的(比如:2个邻居是红色,2 个邻居是蓝色,还有 1 个是绿色)。

    3. 模型的超参数选择(以K-NN为例)

      在模型的实际使用过程中,K-NN分类器中的 K 选取多少较为合适,计算距离使用 L1 范数还是 L2 范数都是需要我们进行选择的,并且称这些参数为超参数。 在超参数调优的过程中决不能使用测试集来进行调优,因为这样会使模型对测试集过拟合,降低模型的泛化能力。所以测试数据集只使用一次,即在训练完成后评价最终的模型时使用。

      把训练集按照50%­-90%的比例分成训练集和验证集,使用训练集训练模型,使用验证集调节超参数。如在 K-NN 中选择超参数 k ,取不同的 k 值用训练集进行训练,之后用检验集进行检验,作图分析出哪个 k 值表现最好,然后用这个 k 值来跑真正的测试集,并作出对算法的评价。

      交叉验证。有时候,训练集数量较小(因此验证集的数量更小),人们会使用一种被称为交叉验证的方法,这种方法更加复杂些。还是用刚才的例子,如果是交叉验证集,我们就不是取 1000 个图像,而是将训练集平均分成 5 份,其中 4 份用来训练,1 份用来验证。然后我们循环着取其中 4 份来训练,其中 1 份来验证,最后取所有 5 次验证结果的平均值作为算法验证结果。 


    图 4 .不同的 K 值对应的KNN分类器结果

     

    如图 4 是份交叉验证对 k 值调优的例子。针对每个 k 值,得到 5 个准确率结果,取其平均值,然后对 
    不同 k 值的平均表现画线连接。本例中,当 k=7 的时算法表现最好(对应图中的准确率峰值)。如果我们将训练集分成更多份数,直线一般会更加平滑(噪音更少)。

      实际应用。在实际情况下,人们不是很喜欢用交叉验证,主要是因为它会耗费较多的计算资源。一般直接把训练集按照50%-­90%的比例分成训练集和验证集。但这也是根据具体情况来定的:如果超参数数量多,你可能就想用更大的验证集,而验证集的数量不够,那么最好还是用交叉验证吧。至于分成几份比较好,一般都是分成3、5和10份。

    4. Nearest Neighbor分类器的优劣

    4.1 NN的优点

      首先,Nearest Neighbor分类器易于理解,实现简单。

      其次,算法的训练不需要花时间,因为其训练过程只是将训练集数据存储起来。

    4.2 NN的缺点

      首先,因为每个测试图像需要和所有存储的训练图像进行比较,所以占用大量存储空间,耗费大量计算资源,测试要花费大量时间计算。因为在实际应用中,我们关注测试效率远远高于训练效率。其实,我们后续要学习的卷积神经网络在这个权衡上走到了另一个极端:虽然训练花费很多时间,但是一旦训练完成,对新的测试数据进行分类非常快。这样的模式就符合实际使用需求。

      其次,在实际的图像分类工作中,很少使用 NN。因为图像都是高维度数据(他们通常包含很多像素),而高维度向量之间的距离通常是反直觉的。下面的图片展示了基于像素的相似和基于感官的相似是有很大不同的: 


    图 5 .L2值相同的不同图片

     

    在高维度数据上,基于像素的的距离和感官上的非常不同。上图中,右边 3 张图片和左边第 1 张原始图片的L2距离是一样的。很显然,基于像素比较的相似和感官上以及语义上的相似是不同的。

      这里还有个视觉化证据,可以证明使用像素差异来比较图像是不够的。z这是一个叫做t-SNE的可视化技术,它将CIFAR-10中的图片按照二维方式排布,这样能很好展示图片之间的像素差异值。在这张图片中,排列相邻的图片L2距离就小。 


    图 6 .将图片进行降维显示

     

    上图使用t-SNE的可视化技术将CIFAR-10的图片进行了二维排列。排列相近的图片L2距离小。可以看出,图片的排列是被背景主导而不是图片语义内容本身主导。具体说来,这些图片的排布更像是一种颜色分布函数,或者说是基于背景的,而不是图片的语义主体。比如,狗的图片可能和青蛙的图片非常接近,这是因为两张图片都是白色背景。从理想效果上来说,我们肯定是希望同类的图片能够聚集在一起,而不被背景或其他不相关因素干扰。为了达到这个目的,我们不能止步于原始像素比较,得继续前进。

    参考文献

    [1]杨金鑫,杨辉华,李灵巧,潘细朋,刘振丙,周洁茜.结合卷积神经网络和超像素聚类的细胞图像分割方法[J/OL].计算机应用研究,2018,(05):1-2(2017-06-14).http://kns.cnki.net/kcms/detail/51.1196.TP.20170614.1318.098.html.

    展开全文
  • kNN分类器

    2019-09-13 10:05:13
    给定一个多标签分类问题。有一些已知标签的数据,然后对未知对象打标签。k均值算法基于这样的假设:(1)距离越近的对象标签相同的概率越大,(2)对象标签分布具有局部一致性 既然局部是一致的,那么就用距离未知...

    参考:https://www.cnblogs.com/bigmonkey/p/7387943.html

    • 原理

    给定一个多标签分类问题。有一些已知标签的数据,然后对未知对象打标签。k均值算法基于这样的假设:(1)距离越近的对象标签相同的概率越大,(2)对象标签分布具有局部一致性

    既然局部是一致的,那么就用距离未知对象最近的k个已知对象的标签给出的分布的众数作为预测类别标签。

    注意:1.在算距离前不同的特征需要去量纲,通常使用线性变换到[0,1]实现

               2.如果从假设(1)出发,考虑更为细致些,就可以设计一个与距离相关的加权贡献分布来替代原始算法的均匀贡献分布(原始算法中k个对象的贡献程度是均匀的),一般用高斯函数加权

    问题:1.怎样的数据适合使用kNN算法,这样的数据如何取训练集合适?

               2.不同的特征重要程度可以不同,能不能通过赋予权重学习这个重要程度的分布?

          

    • 实践

    使用《机器学习实战》中的代码,进行一定的改动。有数据1000例,从中随机选出[50, 500)例作为测试集,其余作为训练集,得到错误率的曲线图:(以下做了多次试验,因为有随机性所以曲线不同)

     

    展开全文
  • KNN分类器-Java实现

    千次阅读 2017-01-05 14:42:31
    KNN,即K近邻算法。其基本思想或者说是实现步骤如下: (1)计算样本数据点到每个已知类别的数据集中点的距离 (2)将(1)中得到的距离按递增顺序排列 (3)选取(2)中前K个点(即与当前样本距离最小的K个...

    KNN,即K近邻算法。其基本思想或者说是实现步骤如下:
    (1)计算样本数据点到每个已知类别的数据集中点的距离
    (2)将(1)中得到的距离按递增顺序排列
    (3)选取(2)中前K个点(即与当前样本距离最小的K个已知类别的数据点)
    (4)统计(3)中得到的K个点所在类别的出现频率
    (5)返回(4)中出现频率最高的类别作为样本点的预测类别
    在给出具体实现代码之前,说明一点:Java下的矩阵操作类基于开源jama包,我自己基于它的源码,做了部分必要的扩充和修改。
    具体实现代码如下:

    /**
     * Created by Song on 2016/9/30.
     */
    public class KnnHandler implements DMHandler {
        //训练集中,每个特征的最小值
        private Matrix minVals;
        //训练集中,每个特征的最大值
        private Matrix maxVals;
        //训练集中,每个特征的取值范围
        private Matrix ranges;
    
        public KnnHandler(Matrix dataSet){
            double [][] minMax = dataSet.getMinMax();
            this.minVals = new Matrix(minMax[0],1);
            this.maxVals = new Matrix(minMax[1],1);
            this.ranges = maxVals.minus(minVals);
        }
        /**
         * 归一化特征值
         * @param dataSet 特征集
         */
        public Matrix autoNorm(Matrix dataSet){
            double[][] norm = dataSet.getArray();
            for(int j=0;j<dataSet.getColumnDimension();j++){
                for(int i=0;i<norm.length;i++){
                    norm[i][j] = (norm[i][j]-minVals.get(0,j))/ranges.get(0,j);
                }
            }
            return new Matrix(norm);
        }
    
        /**
         * K近邻算法
         * @param sample 待评估样本
         * @param dataSet 数据集
         * @param labels 数据集中,每行数据对应的类别
         * @param rate 将距离按由小至大排列,按比例选择固定数量的类别
         */
        public double classify(Matrix sample,Matrix dataSet,Matrix labels,double rate){
            //统计样本频率
            HashMap<Double,Integer> levels = new HashMap<Double, Integer>();
            //遍历类别,得出一共有几类
            for(int i=0;i<labels.getRowDimension();i++){
                if(!levels.containsKey(labels.get(i,0))) levels.put(labels.get(i,0),0);
            }
            //获得距离,并递增排序
            Matrix sortedDistance = sample.distance(dataSet).expand(labels,true).sort();
            //取前num个数据
            int num = (int)Math.ceil(sortedDistance.getRowDimension()*rate);
            for(int i=0;i<num;i++){
                levels.put(sortedDistance.get(i,1),levels.get(sortedDistance.get(i,1))+1);
            }
            //按频率排序
            double targetLevel = 0;
            int count = 0;
            for(double key:levels.keySet()){
                if(levels.get(key)>count) {
                    count = levels.get(key);
                    targetLevel = key;
                }
            }
            return targetLevel;
        }
        //测试
        public static void main(String [] args){
            //随机生成训练集(已知类别)
            Random random = new Random();
            double [][] dataSet = new double[100][4];
            for(int i=0;i<100;i++){
                for(int j=0;j<4;j++){
                    dataSet[i][j]=random.nextInt(10);
                }
            }
            //训练集中100组数据对应的类别
            double [] lables = new double[100];
            for(int i=0;i<100;i++){
                lables[i]=i/10;
            }
            //生成待分类样本
            double [] sample = {1,2,3,4};
            //KNN操作类实例化
            KnnHandler handler = new KnnHandler(new Matrix(dataSet));
            //handler.autoNorm(new Matrix(dataSet)).print(4,3);
            //输出分类结果
            System.out.println(handler.classify(new Matrix(sample,1),new Matrix(dataSet),new Matrix(lables,1).transpose(),0.3));
        }
    }
    

    其中部分函数,例如构造器中获得数据集中每个特征的最小最大取值(即一个二维数组中每列值的最小最大值)方法getMinMax()等,都是自己基于jama源码扩充得到的,原理很简单,此处就不列出来了。
    可以看出,KNN分类是一种非常基础的分类算法,适用于数值型数据。通过计算未知数据点到已知数据点的距离,来判断其具体分类。

    展开全文
  • 构建一个KNN分类器来进行图像分类 K-NN原理介绍 K近邻算法(K-NN)算法是一种简单但也很常用的一种分类算法,它也可以应用于回归计算。K-NN是无参数学习,这意味着它不会对底层数据的分布做出任何假设。它是基于...

    构建一个KNN分类器来进行图像分类

    K-NN原理介绍

    K近邻算法(K-NN)算法是一种简单但也很常用的分类算法,它也可以应用于回归计算。K-NN是无参数学习,这意味着它不会对底层数据的分布做出任何假设。它是基于实例,即该算法没有显式地学习模型。相反,它选择的是记忆训练实例,并在一个有监督的学习环境中使用。KNN算法的实现过程主要包括距离计算方式的选择、k值得选取以及分类的决策规则三部分。

    1. 距离计算方式的选择

    选择一种距离计算方式,计算测试数据与各个训练数据之间的距离。距离计算方式一般选择欧氏距离或曼哈顿距离。
    给定训练集: Xtrain=(x(1),x(2),x(3),...,x(i)),测试集:Xtest=(x(1),x(2),x(3),...,x(j))
    则欧式距离为:

    (1)d(x(i),x(j))=l=1l(xl(i)xl(j))2

    曼哈顿距离为:
    (2)d(x(i),x(j))=l=1l|xl(i)xl(j)|

    2. k值得选取

    在计算测试数据与各个训练数据之间的距离之后,首先按照距离递增次序进行排序,然后选取距离最小的k个点。
    一般会先选择较小的k值,然后进行交叉验证选取最优的k值。k值较小时,整体模型会变得复杂,且对近邻的训练数据点较为敏感,容易出现过拟合。k值较大时,模型则会趋于简单,此时较远的训练数据点也会起到预测作用,容易出现欠拟合。

    3. 分类的决策规则

    常用的分类决策规则是取k个近邻训练数据中类别出现次数最多者作为输入新实例的类别。即首先确定前k个点所在类别的出现频率,对于离散分类,返回前k个点出现频率最多的类别作预测分类;对于回归则返回前k个点的加权值作为预测值。

    学习目标

    • 不使用循环计算测试数据与训练数据的距离
    • 构建KNN分类器来进行图像二分类
    • 构建KNN分类器来进行图像多分类

    构建KNN分类器来进行图像二分类

    第一步:数据预处理

    导入库

    import numpy as np
    import os
    import pickle
    import matplotlib.pyplot as plt
    import h5py
    import scipy
    from PIL import Image
    from scipy import ndimage
    
    %matplotlib inline

    导入数据集

    数据集介绍:
    此数据集总共包含259张图像,每张图像大小为64*64*3,分为两类(含有猫和不含猫)。其中训练集包含209张图像,测试集包含50张图像。

    dataset shape
    train_set_x_orig (209,64,64,3)
    test_set_x_orig (50,64,64,3)
    train_set_x (209,1)
    test_set_y (50,1)
    def load_dataset():
        train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")
        train_set_x_orig = np.array(train_dataset["train_set_x"][:])
        train_set_y_orig = np.array(train_dataset["train_set_y"][:])
    
        test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")
        test_set_x_orig = np.array(test_dataset["test_set_x"][:])
        test_set_y_orig = np.array(test_dataset["test_set_y"][:])
    
        classes = np.array(test_dataset["list_classes"][:])
    
        train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
        test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))
    
        return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
    train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()

    将数据集转换为矢量

    train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T
    test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0],-1).T

    数据标准化

    train_set_x = train_set_x_flatten/255.
    test_set_x = test_set_x_flatten/255.

    第二步:构建KNN分类器

    计算距离(欧式距离)

    def distance(X_test, X_train):
        """
        输入:
        X_test -- 由numpy数组表示的测试集,大小为(图片长度 * 图片高度 * 3 , 测试样本数)
        X_train -- 由numpy数组表示的训练集,大小为(图片长度 * 图片高度 * 3 , 训练样本数)
        输出:
        distances -- 测试数据与各个训练数据之间的距离,大小为(测试样本数, 训练样本数量)的numpy数组
        """
        num_test = X_test.shape[1]
        num_train = X_train.shape[1]
        distances = np.zeros((num_test, num_train))
        # (X_test - X_train)*(X_test - X_train) = -2X_test*X_train + X_test*X_test + X_train*X_train
        dist1 = np.multiply(np.dot(X_test.T,X_train), -2)    # -2X_test*X_train, shape (num_test, num_train)
        dist2 = np.sum(np.square(X_test.T), axis=1, keepdims=True)    # X_test*X_test, shape (num_test, 1)
        dist3 = np.sum(np.square(X_train), axis=0,keepdims=True)    # X_train*X_train, shape(1, num_train)
        distances = np.sqrt(dist1 + dist2 + dist3)
    
        return distances

    第三步:定义预测函数

    def predict(X_test, X_train, Y_train, k = 1):
        """ 
        输入:
        X_test -- 由numpy数组表示的测试集,大小为(图片长度 * 图片高度 * 3 , 测试样本数)
        X_train -- 由numpy数组表示的训练集,大小为(图片长度 * 图片高度 * 3 , 训练样本数)
        Y_train -- 由numpy数组(向量)表示的训练标签,大小为 (1, 训练样本数)
        k -- 选取与训练集最近邻的数量
        输出:
        Y_prediction -- 包含X_test中所有预测值的numpy数组(向量)
        distances -- 由numpy数组表示的测试数据与各个训练数据之间的距离,大小为(测试样本数, 训练样本数)
        """
        distances = distance(X_test, X_train)
        num_test = X_test.shape[1]
        Y_prediction = np.zeros(num_test)
        for i in range(num_test):
            dists_min_k = np.argsort(distances[i])[:k]     # 按照距离递增次序进行排序,选取距离最小的k个点 
            y_labels_k = Y_train[0,dists_min_k]     # 确定前k个点的所在类别
            Y_prediction[i] = np.argmax(np.bincount(y_labels_k)) # 返回前k个点中出现频率最高的类别作为测试数据的预测分类
    
        return Y_prediction, distances

    定义模型

    def model(X_test, Y_test, X_train, Y_train, k = 1, print_correct = False):
        """
        输入:
        X_test -- 由numpy数组表示的测试集,大小为(图片长度 * 图片高度 * 3 , 测试样本数)
        X_train -- 由numpy数组表示的训练集,大小为(图片长度 * 图片高度 * 3 , 训练样本数)
        Y_train -- 由numpy数组(向量)表示的训练标签,大小为 (1, 训练样本数)
        Y_test -- 由numpy数组(向量)表示的测试标签,大小为 (1, 测试样本数)
        k -- 选取与训练集最近邻的数量
        print_correct -- 设置为true时,打印正确率
        输出:
        d -- 包含模型信息的字典
        """
        Y_prediction, distances = predict(X_test, X_train, Y_train, k)
        num_correct = np.sum(Y_prediction == Y_test)
        accuracy = np.mean(Y_prediction == Y_test)
        if print_correct:
            print('Correct %d/%d: The test accuracy: %f' % (num_correct, X_test.shape[1], accuracy))
        d = {"k": k,
             "Y_prediction": Y_prediction, 
             "distances" : distances,
             "accuracy": accuracy}
        return d

    测试模型

    d = model(test_set_x, test_set_y,train_set_x, train_set_y, k=1, print_correct = True)
    Correct 37/50: The test accuracy: 0.740000
    
    num_px = train_set_x_orig.shape[1]
    index = 1
    plt.imshow(test_set_x[:,index].reshape((num_px, num_px, 3)))
    print ("y = " + str(test_set_y[0,index]) + ", you predicted that it is a \"" + classes[int(d["Y_prediction"][index])].decode('utf-8') +  "\" picture.")
    y = 1, you predicted that it is a "cat" picture.
    

    这里写图片描述

    构建KNN分类器来进行图像多分类

    导入数据集

    def load_CIFAR_batch(filename):
        with open(filename, 'rb') as f:
            datadict = pickle.load(f,encoding='latin1')
            X = datadict['data']
            Y = datadict['labels']
            X = X.reshape(10000, 3, 32, 32).transpose(0,2,3,1).astype("float")
            Y = np.array(Y)
        return X, Y
    def load_CIFAR10():
        xs = []
        ys = []
        for b in range(1,6):
            f = os.path.join('datasets', 'cifar-10-batches-py', 'data_batch_%d' % (b, ))
            X, Y = load_CIFAR_batch(f)
            xs.append(X)
            ys.append(Y)    
        Xtr = np.concatenate(xs)
        Ytr = np.concatenate(ys)
        del X, Y
        Xte, Yte = load_CIFAR_batch(os.path.join('datasets', 'cifar-10-batches-py', 'test_batch'))
        return Xtr, Ytr, Xte, Yte
    X_train, y_train, X_test, y_test = load_CIFAR10()

    CIFAR-10数据集介绍

    CIFAR-10数据集共有60000张彩色图像,每张图像大小为32*32*3,分为10个类,每类6000张图片。其中训练集包含50000张图像,测试集包含10000张图像。

    dataset shape
    X_train (50000,32,32,3)
    X_test (10000,32,32,3)
    y_train (50000,)
    y_test (10000,)

    CIFAR-10数据集部分图像可视化

    classes = ['plane', 'car', 'bird', 'cat', 'dear', 'dog', 'frog', 'horse', 'ship', 'truck']
    num_classes = len(classes)
    num_each_class = 7
    
    for y, cls in enumerate(classes):
        idxs = np.flatnonzero(y_train == y)
        idxs = np.random.choice(idxs, num_each_class, replace=False)
        for i, idx in enumerate(idxs):
            plt_idx = i * num_classes + (y + 1)
            plt.subplot(num_each_class, num_classes, plt_idx)
            plt.imshow(X_train[idx].astype('uint8'))
            plt.axis('off')
            if i == 0:
                plt.title(cls)
    plt.show()

    这里写图片描述

    取训练集的前10000个样本与测试集的前1000个样本

    X_train = np.reshape(X_train, (X_train.shape[0], -1)).T
    X_test = np.reshape(X_test, (X_test.shape[0], -1)).T
    Y_set_train = y_train[:10000].reshape(1,-1)
    Y_set_test = y_test[:1000].reshape(1,-1)
    X_set_train = X_train[:,:10000]
    X_set_test = X_test[:,:1000]

    取不同的k值进行训练

    models = {}
    for k in [1, 3, 5, 10]:
        print ("k = " + str(k))
        models[str(k)] = model(X_set_test, Y_set_test, X_set_train, Y_set_train, k, print_correct = True)
        print ('\n' + "-------------------------------------------------------" + '\n')
    k = 1
    Correct 283/1000: The test accuracy: 0.283000
    
    -------------------------------------------------------
    
    k = 3
    Correct 280/1000: The test accuracy: 0.280000
    
    -------------------------------------------------------
    
    k = 5
    Correct 296/1000: The test accuracy: 0.296000
    
    -------------------------------------------------------
    
    k = 10
    Correct 288/1000: The test accuracy: 0.288000
    
    -------------------------------------------------------
    

    画出不同k值对应的测试精度曲线

    models = {}
    k = []
    accuracys = []
    for i in range(1,11):
        models[str(i)] = model(X_set_test, Y_set_test, X_set_train, Y_set_train, i, print_correct = False)
        k.append(models[str(i)]["k"])
        accuracys.append(models[str(i)]["accuracy"])
    plt.plot(k, accuracys)
    plt.ylabel('accuracy')
    plt.xlabel('k')
    plt.show()

    这里写图片描述

    数据集下载地址
    github
    csdn

    展开全文
  • KNN分类器

    千次阅读 2015-07-08 12:36:25
    KNN学习(K-Nearest Neighbor algorithm,K最邻近方法 )是一种统计分类器,对数据的特征变量的筛选尤其有效。基本原理KNN的基本思想是:输入没有标签(标注数据的类别),即没有经过分类的新数据,首先提取新数据的...
  • 从第一个算法kNN分类器开始,记录自己的学习经历。 kNN分类器和Python算法实现  假设生活中你突然遇到一个陌生人,你对他很不了解,但是你知道他喜欢看什么样的电影,喜欢穿什么样的衣服。根据以前你的认知,你把...
  • matlab KNN分类器代码

    2020-07-30 23:32:25
    KNN分类器的实现 不同范式求近邻,还有余弦相似
  • KNN分类器完整的matlab代码

    热门讨论 2020-07-29 15:58:02
    可以通过使用KNN分类器进行图片分类,KNN分类器完整的matlab代码。
  • HALCON示例程序classify_image_class_knn.hdev使用KNN分类器对多通道图像进行分割。这个例子介绍了使用KNN分类器对彩色图片进行分割的方法,KNN分类器的使用过程为:create_class_knn 、add_samples_image_class_knn...
  • 利用python实现KNN分类器

    千次阅读 2014-09-27 17:27:49
    熟悉KNN分类器已经
  • 在写代码的时候,我一开始将训练、测试集的标签转化为了one_hot表示方式,...其他的部分都是基于numpy模块和前一篇博文实现的knn分类器,有关knn分类器的实现大家参考我的这一片博文: https://blog.csdn.net/weixi...
  • 机器学习(8)--创建KNN分类器

    千次阅读 2018-03-01 19:21:52
    创建KNN分类器 KNN(k-nearest neighbors) 是使用k个最近邻的训练数据集来寻找对象分类的方法,如果希望将数据分类 可以找到一个KNN并做一个多数表决 代码实现如下: # -*- coding:utf-8 -*- # 导入基本模块...
  • KNN 分类器原理

    千次阅读 2017-04-14 09:59:22
    最简单平凡的分类器也许是那种死记硬背式的分类器,记住所有的训练数据,对于新的数据则直接和训练数据匹配,如果存在相同属性的训练数据,则直接用它的分类来作为新数据的分类。这种方式有一个明显的缺点,那就是很...
  • kNN基本分类器,以及两个运用kNN算法的实例:约会网站的配对和手写识别系统,包含数据源。
  • knn分类器寻找最佳K值

    2019-12-19 11:28:49
    knn分类器寻找最佳K值 网格搜索 pipe管道 ​ # 寻找最佳的K值 from sklearn.neighbors import KNeighborsClassifier from sklearn import datasets from sklearn.preprocessing import StandardScaler from sklearn....
  • 用matlab写的代码,采用KNN实现多分类,代入数据就可以成功运行!
  • 1 KNN算法 1.1 KNN算法简介 KNN(K-Nearest Neighbor)工作原理:存在一个样本数据集合,也称为训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类对应的关系。输入没有标签的数据...
  • 今天跟着教程写了一个我的第一个机器学习算法,之前上课的时候学到了一些原理,但是自己...#第一个机器学习算法 KNN分类器 from scipy.spatial import distance def euc(a,b):#计算欧氏距离 return distance.euclide
  •  * KNN分类器  * @author ysh 1208706282  *  */ public class KNN {  Set labelSet;  List samples;  /**  * 样本  * @author Administrator  *  */  static class Sample
  • 基于距离学习的集成KNN分类器,于飞,顾宏,近年来,数据挖掘引起了信息产业界的极大关注,其主要原因是存在大量数据,可以广泛适用,并且迫切需要将这些数据转换成有用的信
1 2 3 4 5 ... 20
收藏数 17,476
精华内容 6,990
关键字:

knn 分类器