机器学习:PCA(实例:MNIST数据集)
一、数据
-
获取数据
import numpy as np from sklearn.datasets import fetch_mldata mnist = fetch_mldata("MNIST original")
- sklearn 的 datasets 中,一个特有的方法:fetch_mldata,使用此方法可以直接从一个官方网站中下载各种机器学习数据;
- 格式:datas = fetch_mldata("字符串");
-
查看数据
mnist # 输出: {'COL_NAMES': ['label', 'data'], 'DESCR': 'mldata.org dataset: mnist-original', 'data': array([[0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], ..., [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0], [0, 0, 0, ..., 0, 0, 0]], dtype=uint8), 'target': array([0., 0., 0., ..., 9., 9., 9.])}
- mnist 是一个字典:'COL_NAMES'、'DESCR'、'data'、'target';
- 'DESCR':表示 MNIST 数据集所在的网站;
-
处理数据
X, y = mnist['data'], mnist['target'] X.shape # 输出:(70000, 784) 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) # 输出:44.9 s knn_clf.score(X_test, y_test) # 输出:0.9688
- kNN 算法中还需要进行调参:k、weight
-
使用 kNN算法进行识别操作(PCA降维数据)
from sklearn.decomposition import PCA # 只保留样本的 90% 的信息 pca = PCA(0.9) pca.fit(X_train) X_train_reduction = pca.transform(X_train) X_train_reduction.shape # 输出:(60000, 87) knn_clf = KNeighborsClassifier() %time knn_clf.fit(X_train_reduction, y_train) # 输出:602 s X_test_reduction = pca.transform(X_test) %time knn_clf.score(X_test_reduction, y_test) # 输出:1 min 27 s 0.9728
- PCA(0.9):只保留样本的 90% 的信息,也就是能解释 90% 原是数据方差的前 n 个主成分;
- (60000, 87):将样本从 784 维,降低至 87 维,保留了样本 90% 的信息;
-
分析:数据使用 PCA 降维前后的效果
- 现象:识别准确度提高了,预测时间缩短了;
- 使用 PCA 将数据降维后的优点:识别准确度提高了,预测时间缩短了,减小了数据和存储空间;
- 疑问:为什么 PCA 的过程中丢失了 10% 的信息,识别准确度反而提高了?
- 答疑:实际上 PCA 这个过程中,不仅仅对原始数据进行了降维,更有可能在降维的过程中将原有的数据所包含的噪音消除了,使得数据集中更好的特征,以至于识别准确率得到提升;