机器学习入门 7-7 试手MNIST数据集

本系列是《玩转机器学习教程》一个整理的视频笔记。本小节使用更大更正规的手写识别数据集MNIST数据集,使用sklearn导入MNIST数据集并使用kNN算法对MNIST数据集进行分类。之后测试使用PCA对MNSIT数据集进行降维后应用kNN算法分类的效果。

01

MNIST数据集及加载

MNIST数据集是由美国高中生和人口普查局员工手写的70000个数字的图像,其中60000张训练图像,10000张测试图像。它是机器学习领域的一个经典数据集,其历史几乎和这个领域一样长,被称为机器学习领域的"Hello World"。因此像sklearn和tensorflow这种机器学习框架都内置了MNIST数据集。

sklearn的datasets中有一个专门的方法fetch_mldata,通过这个方法可以从一个官网上下载各式各样的机器学习数据集,传入的参数字符串"MNIST original"表示我们要下载的是MNSIT原始数据集。具体代码如下:

import numpy as np
from sklearn.datasets import fetch_mldata
# 加载MNIST数据集
mnist = fetch_mldata("MNIST original")

但是在实际使用中,会抛出异常:

第一次使用MNIST数据集的时候,需要去官网上下载,下次再使用的话就可以直接去指定目录上加载数据集。由于这是第一次通过sklearn加载MNIST数据集,因此需要去官网进行下载,但是会抛出链接超时的异常,可能服务器在国外,国内访问的话需要进行翻墙处理。

但是我们可以自行下载数据集,然后移动到指定的目录中,具体的下载地址如下:

  1. GitHub下载(不推荐,很慢):https://github.com/amplab/datascience-sp14/raw/master/lab7/mldata/mnist-original.mat
  2. 百度网盘:https://pan.baidu.com/s/1PcEsFps6NHBRWVxBMl7SmQ 提取码:pz8t

下载完成后会有一个名为"mnist-original.mat"的文件。之后将下载好的数据集文件放到sklearn数据根目录下的mldata目录。可以通过下面方法查询mldata目录:

我的电脑上的目录为"C:\Users\Chenkc\scikit_learn_data",找到对应的目录,发现在路径下有一个mldata文件夹,将下载的"mnist-original.mat"文件移到mldata文件夹下。

完成了这些操作就可以不用下载直接加载MNSIT数据集了。

此时mnist变量得到的是一种类似字典的数据,可以通过Python操作字典的函数对其进行操作。DESCR字段给出了下载数据集的网站"mldata.org",如果有兴趣可以访问这个网站,看看其他的数据集。此时我们只关注target和data两个字段,data对应的就是X,而target对应的就是y。

按照正常的机器学习流程,得到数据集之后需要使用train_test_split方法对其进行划分,划分一定比例的训练集以及测试集,但是对于MNIST数据集而言,已经帮我们划分好的训练集和测试集,我们只需要对ndarray数组进行切片分割即可。同时通过mnist中关于data和target的描述可以看出,它们数组类型都是int,因此为了方便机器学习的过程,在切片过程中,显示的指定ndarray数组类型为float浮点型。

02

使用kNN分类算法

有了X和y,接下来就可以使用kNN算法进行分类。

在MNSIT数据集中,kNN算法的训练(fit)过程耗时39.6s。根据前面对kNN的介绍,kNN的训练(fit)过程是将训练数据集拷贝,其实不完全这样,对于sklearn实现的kNN算法,当处理比较大的样本数据时,会自动使用kd树和Ball树这样的树结构来进行存储,来相应的加快kNN的过程。当前的样本比较大,需要39.6s就可以了。

对于kNN分类算法而言,预测过程是更耗时的,因为在kNN的预测过程中,需要比对所有样本之间距离,才能找到前k近的样本,然后进行投票。以我的电脑配置,预测花费了21分钟。

还有一点需要注意的,在前面介绍kNN进行分类的过程中,都使用了StandardScaler将数据归一化,但是在应用MNIST数据集的时候,并没有使用归一化。其实原因很简单,前面介绍kNN求预测样本与所有样本之间距离的时候,由于不同维度特征的量纲不同,计算距离的时候,很容易受部分特征的主导,这种情况下计算出来的距离可能有偏差,不能非常好的同时反映样本中每一个特征维度的重要程度,因此我们才选择对数据进行归一化处理。但是对于MNIST数据集而言,784维度特征,每一个维度都是0-255之间表示的亮度值,因此每一个维度特征都处在相同量纲上,因此计算出来的距离不会受到某部分特征的影响,计算得到的距离更有意义。

03

使用PCA降维后的kNN算法

简单回顾前面没有使用PCA进行降维的MNIST数据集,在应用kNN算法进行分类的效果:

  1. 训练时间:39.6S
  2. 预测时间:21min 5s
  3. 分类精度:0.9688

接下来先使用PCA对MNIST数据集降维,之后通过kNN分类算法对降维后的MNIST数据集进行分类。

由于样本量比较大,所以保留的信息稍微少一些,只保留了90%的信息,当然通过降维后数组的shape可以看出,保留90%的信息,将MNIST数据集的784维度的特征降到了87维,这个降维比例还是相当可观的,这样的降维在具体运算的时候会提速不少。

结果:

  1. 训练时间:862ms
  2. 预测时间:53s
  3. 分类精度:0.9728

我们通过53s的时间就预测完了所有的X_test测试集,比之前的21min5s快了很多倍,同时预测的准确率也是非常可观的。

这里可能会有疑问?为什么降维后的分类准确率不降反增呢?

上面的得到的是一个非常好的结果,这为我们直接带来两个非常明显的改进:

  1. 数据的特征维度降低,相应的存储数据的空间变小,训练预测过程所消耗的时间也会减少;
  2. 分类的准确率提高了;

对于第一点很好理解,特征维度大幅度降低,参与运算的计算随之减少。对于第二点,在我们印象中,PCA降维后丢失了很多信息,我们传入0.9也可以知道,我们选择丢失了10%的信息,但是丢失了数据的信息,准确率反而提高了。这就涉及到PCA另外一个非常重要的应用:降噪,降噪故名思议就是减少噪声的影响,所以PCA对数据降维的过程中,虽然丢失了一些信息,但是这些信息可能包含的是一些噪声因素,这些噪声可能会影响样本数据的一些分布,导致分类的结果受到这些噪声的影响。将原有数据所包含的噪声消除后,这使得我们可以更好更准确的拿到数据集对应的特征,从而使得识别的准确率得到提升。

本文分享自微信公众号 - AI机器学习与深度学习算法(AI-KangChen)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券