pca mnist matlab,机器学习系列(二十)——PCA在手写数字数据集的应用

本篇将在真实数据集——手写数字数据集上使用PCA。

PCA应用到真实数据集

简单手写数字数据集包括1797个样本,每个样本都是一个8×8的灰度图像,可以看作每个样本有64个特征。导入手写数字数据集:

import numpy as np

import matplotlib.pyplot as plt

from sklearn import datasets

digits = datasets.load_digits()

X = digits.data

y = digits.target

首先不做pca降维直接用knn算法对其分类:

from sklearn.model_selection import train_test_split

X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=666)

X_train.shape

%%time

'''不对数据降维,使用knn对手写数字分类并测试性能'''

from sklearn.neighbors import KNeighborsClassifier

knn_clf = KNeighborsClassifier()

knn_clf.fit(X_train,y_train)

时间消耗和准确率:

b9f21b956cab

knn时间消耗

b9f21b956cab

准确率

有上面的结果看到,直接使用knn准确率达到98.7%。接下来将数据降到2维,再使用knn算法:

'''PCA降维后,使用knn'''

from sklearn.decomposition import PCA

pca = PCA(n_components=2)

pca.fit(X_train)

X_train_reduction = pca.transform(X_train)

X_test_reduction = pca.transform(X_test)

%%time

knn_clf = KNeighborsClassifier()

knn_clf.fit(X_train_reduction,y_train)

降维后时间消耗和准确率:

b9f21b956cab

2维时间消耗

b9f21b956cab

2维准确率

降到2维后由于数据量减少,训练速度比未降维的时候快的多,不过准确率却只有60.7%,这是因为数据由64维到2维,损失太多信息了,也许应该降到10维,20维什么的。实际上我们可以通过不断搜索不同维数进行数据集训练以得到更合适的维数。不过sklearn的pca中提供了一个指标explained_variance_ratio_,对于降到2维,该指标为:

b9f21b956cab

e_v_r2

这个指标结果表示第一个轴方向能解释0.146原数据的方差,第二个轴能解释0.137原数据的方差,而剩下70%多的方差则由于降维而丢失。该指标大小是从大到小排列的,其数值即对应每个方向(主成分)的重要程度。下面对该64维数据提取其所有主成分,并给出该指标:

pca = PCA(n_components=X_train.shape[1])

pca.fit(X_train)

pca.explained_variance_ratio_

指标如下:

b9f21b956cab

主成分重要程度排序

可以发现最后几个轴方向解释的方差还不到0.0001%,因此最后几个主成分是可以忽略的。

将主成分个数和它们能解释的总方差百分比绘图:

'''表示取前n个主成分能解释多少百分比的方差'''

plt.plot([i for i in range(X_train.shape[1])],\

[np.sum(pca.explained_variance_ratio_[:i+1]) for i in range(X_train.shape[1])])

plt.show()

b9f21b956cab

主成分解释方差百分比

由图看出如果我们需要解释原方差的95%,则取前大约30个主成分即可。这在sklearn的pca中也是能直接求的,比如我们要求主成分个数应能至少解释95%的方差:

pca = PCA(0.95)

pca.fit(X_train)

pca.n_components_

b9f21b956cab

解释95%方差需要的主成分

可见需要28个主成分。取前28个主成分后的数据集进行训练结果如下:

b9f21b956cab

训练结果

达到了98%的准确率。虽然比未降维的数据准确率要低,但0.006的差距也还可以接受,而且时间消耗要少的多。有时我们愿意用微小的准确率差换取时间性能的优势。

PCA用于MNIST数据集

MNIST数据集是机器学习领域中非常经典的一个数据集,共有70000个样本,由60000个训练样本和10000个测试样本组成,每个样本有784个特征,是一张28 * 28像素的灰度手写数字图片。

首先是从sklearn下下载sklearn数据集,这里要注意的是,不同机器学习框架下都有mnist数据集,他们可能格式不太一样。

from sklearn.datasets import fetch_openml

mnist = fetch_openml("MNIST original",data_home = 'datasets')

当然第一次下载可能需要一会儿时间,或者下载报错,这里给出笔者下载好的保存在百度云的mnist数据集链接:

链接: https://pan.baidu.com/s/1L8F9e3fHF3Nnd8yhvS7_zw 提取码: wb52

下面对数据进行训练:

X,y = mnist['data'],mnist['target']

X_train = np.array(X[:60000],dtype=float)

y_train = np.array(y[:60000],dtype=float)

X_test = np.array(X[60000:],dtype=float)

y_test = np.array(y[60000:],dtype=float)

'''使用knn'''

from sklearn.neighbors import KNeighborsClassifier

knn_clf = KNeighborsClassifier()

%time knn_clf.fit(X_train,y_train)

b9f21b956cab

knn训练时间消耗

对训练的模型进行准确率评价:

b9f21b956cab

准确率

由于knn算法预测过程需要所有训练数据参与,而mnist数据量庞大,因此及其消耗时间,在笔者的PC上用时13分钟,准确率96.9%

接下来用PCA对数据进行降维,然后再用knn训练:

from sklearn.decomposition import PCA

pca = PCA(0.9)

pca.fit(X_train)

X_train_reduction = pca.transform(X_train)

这里PCA中参数给了0.9,扔掉了训练数据集10%的信息:

b9f21b956cab

降维数据shape

此时784个特征只剩下87了,执行训练过程:

'''降维后使用knn'''

knn_clf1 = KNeighborsClassifier()

%time knn_clf1.fit(X_train_reduction,y_train)

b9f21b956cab

降维后knn训练

准确率:

b9f21b956cab

降维后准确率

发现预测过程用时明显减少,而且准确率97.3%比之前高,咦?为什么丢掉数据10%的信息准确率却更高了呢?这涉及到PCA的一个很重要的应用,那就是数据降噪,丢掉的数据很大程度上是噪声。降噪的更多例子将在下篇介绍。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值