MNIST数据集的导入与预处理
Posted zstar-_
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MNIST数据集的导入与预处理相关的知识,希望对你有一定的参考价值。
在做KNN+LDA对MNIST数据集分类时遇到了不少坑,本篇文章主要是记录一下解决这些坑的方案,完整的代码和实验报告等作业结束提交后再进行上传。
MNIST数据集
MNIST数据集简介
MNIST数据集,是一组由美国高中生和人口调查局员工手写的70000个数字的图片。每张图像都用其代表的数字标记。这个数据集被广为使用,因此也被称作是机器学习领域的“Hello World”。
MNIST数据集的获取
MNIST数据集网上流传的大体上有两类,不过两者有些不同,第一种是每幅图片大小是2828的,第二种是每幅图片大小是3232的,官网下载的是哪种不作细究,因为可以通过更简单的数据获取方法。(PS:官网下载的数据集已经划分好了60000个训练集和标签,10000个测试集和标签,共四个文件,但格式不是常见文件格式,需要手动转化。第二类数据集是matlab中的.mat表格文件,两类数据我都打包上传到资源里了,未过审核,暂时不放链接,需要的话可以评论或者到我的主页资源内寻找)
现在说说更简单的数据获取方式——使用openml
openml官网:https://www.openml.org/
在本实验中可以这样进行MNIST数据集的导入
from sklearn.datasets import fetch_openml
mnist = fetch_openml("mnist_784")
X, y = mnist['data'], mnist['target'] # X:data,y:label
print(X.shape, y)# 70000 70000
注:mnist_784代表每个图片都是28*28的尺寸,其它数据集也可以使用类似导入方式,但要去官网搜该数据集的命名方式。老版本导入数据集叫fetch_data,在sklearn2.0版本之后已无法使用。
数据截取
为什么要数据的截取?
对于KNN来说,将MNIST的6-7万数据全扔进去会导致运行极其缓慢。
当k=5时,我运行单次的结果就花费了近5分钟。
可以看到我这里的i7-CPU全部使用,也很难撑住。
因此,可以通过下面的代码随机选取10000个数据作数据样本。
shuffle_index = np.random.permutation(60000) # 随机排列一个序列,返回一个排列的序列。
X1, y1 = X[shuffle_index[:10000]], y[shuffle_index[:10000]]
数据预处理
原始的数据的灰度图像每一个像素点都是-256~256的,通过数据标准化和归一化可以加快计算效率。
下面是一些数据预处理的方式
摘自 知乎
Zero-mean normalization
公式:
X
=
(
x
−
μ
)
/
σ
X=(x-\\mu)/\\sigma
X=(x−μ)/σ
这就是均值方差归一化,这样处理后的数据将符合标准正太分布,常用在一些通过距离得出相似度的聚类算法中,比如 K-means。
Min-max normalization
公式:
X
=
(
x
−
X
m
i
n
)
/
(
X
m
a
x
−
X
m
i
n
)
X=(x-Xmin)/(Xmax-Xmin)
X=(x−Xmin)/(Xmax−Xmin)
min-max 归一化的手段是一种线性的归一化方法,它的特点是不会对数据分布产生影响。不过如果你的数据的最大最小值不是稳定的话,你的结果可能因此变得不稳定。min-max 归一化在图像处理上非常常用,因为大部分的像素值范围是 [0, 255]。
Non-linear normaliztions
非线性的归一化函数包含 log,exp,arctan, sigmoid等等。用非线性归一化的函数取决于你的输入数据范围以及你期望的输出范围。比如 log() 函数在 [0, 1] 区间上有很强的区分度,arctan() 可以接收任意实数病转化到
[
−
π
/
2
,
π
/
2
]
[-\\pi/2,\\pi/2]
[−π/2,π/2]
Length-one normalization
公式:
X
=
x
/
∥
x
∥
X=x/\\Vert x \\Vert
X=x/∥x∥
将特征转为单位向量的形式,可以剔除特征的强度的影响。这种处理用在不考虑向量大小而需要考虑向量方向的问题中,比如在一些文本情感的分类中,我们可能并不需要知道情感表达的强弱,而只要知道情感的类型,比如开心,生气等等。
对sklearn来说,数据预处理主要需弄清楚fit,transform,fit_transform三个接口。
关于数据预处理更详细的内容之后会在我的专栏sklearn内进行后续更新。
LDA函数的一些参数
最后一个坑是使用LDA降维的一些参数设置,这里参考用scikit-learn进行LDA降维,整理如下:
LinearDiscriminantAnalysis类:
1)solver
: 即求LDA超平面特征矩阵使用的方法。可以选择的方法有奇异值分解"svd",最小二乘"lsqr"和特征分解"eigen"。一般来说特征数非常多的时候推荐使用svd,而特征数不多的时候推荐使用eigen。主要注意的是,如果使用svd,则不能指定正则化参数shrinkage进行正则化。默认值是svd
2)shrinkage
:正则化参数,可以增强LDA分类的泛化能力。如果仅仅只是为了降维,则一般可以忽略这个参数。默认是None,即不进行正则化。可以选择"auto",让算法自己决定是否正则化。当然我们也可以选择不同的[0,1]之间的值进行交叉验证调参。注意shrinkage只在solver为最小二乘"lsqr"和特征分解"eigen"时有效。
3)priors
:类别权重,可以在做分类模型时指定不同类别的权重,进而影响分类模型建立。降维时一般不需要关注这个参数。
4)n_components
:即我们进行LDA降维时降到的维数。在降维时需要输入这个参数。注意只能为[1,类别数-1)范围之间的整数。如果我们不是用于降维,则这个值可以用默认的None。
如果我们只是为了降维,则只需要输入n_components,注意这个值必须小于“类别数-1”。PCA没有这个限制。
以上是关于MNIST数据集的导入与预处理的主要内容,如果未能解决你的问题,请参考以下文章