PCA的形象说明导入数据PCA后可视化建立模型性能评测
特征降维有两个目的:其一,我们会经常在实际项目中遭遇特征维度非常之高的训练样本,而往往又无法借助自己的领域知识人工构建有效特征;其二,在数据表现方面,我们无法用肉眼观测超过三个维度的特征。因此,特征降维不仅重构了有效的低维度特征向量,同时也为数据展现提供了可能。在特征降维的方法中,主成分分析(PrincipalComponentAnalysis)是最为经典和实用的特征降维技术,特别在辅助图像识别方面有突出的表现。
PCA的形象说明
有一组2X2的数据[(1, 2),(2, 4)}]。假设这两个数据都反映到一个类别(分类)或者一个类簇(聚类)。如果我们的学习模型是线性模型,那么这两个数据其实只能帮助权重参数更新一次,因为他们线性相关,所有的特征数值都只是扩张了相同的倍数;如果使用PCA分析的话,这个矩阵的“秩”是1,也就是说,在多样性程度上,这个矩阵只有一个自由度。
代码语言:javascript复制#导人numpy工具包。
import numpy as np
#初始化一个2* 2的线性相关矩阵。
M = np.array([[1, 2],[2, 4]])
#计算2* 2线性相关矩阵的秩。
np.linalg.matrix_rank(M, tol= None)
代码语言:javascript复制1
导入数据
将用到“手写体数字图像”全集数据,从PCA展示数据的角度出发,为大家显示经过PCA处理之后,这些数字图像映射在二维空间的分布情况。
代码语言:javascript复制#导入pandas用于数据读取和处理。
import pandas as pd
digits_train = pd.read_csv('optdigits.tra',header= None)
digits_test = pd.read_csv('optdigits.tes',header= None)
#分割训练数据的特征向量和标记。
x_digits = digits_train[np.arange (64)]
y_digits = digits_train[64]
PCA后可视化
把原始六十四维度的图像压缩到只有二个维度的特征空间,依然可以发现绝大多数数字之间的区分性
代码语言:javascript复制#从sklearn .decomposition导人PCA。
from sklearn.decomposition import PCA
#初始化一个可以将高维度特征向量(六十四维)压缩至二个维度的PCA。
estimator = PCA(n_components = 2)
x_pca = estimator.fit_transform(x_digits)
#显示10类手写体数字图片经PCA压缩后的2维空间分布。
from matplotlib import pyplot as plt
def plot_pca_scatter():
colors= ['black', 'blue', 'purple', 'yellow', 'white', 'red', 'lime','cyan', 'orange', 'gray']
for i in range (len(colors)) :
px = x_pca[:, 0][y_digits.values==i]
py = x_pca[:, 1][y_digits.values==i]
plt.scatter(px, py, c=colors[i])
plt.legend(np.arange(0,10).astype(str))
plt.xlabel('First Principal Component')
plt.ylabel ('Second Principal Component')
plt.show ()
plot_pca_scatter()
在这里插入图片描述
建立模型
分别训练两个以支持向量机(分类)为基础的手写体数字图像识别模型,其中一个模型使用原始六十四维度的像素特征,另一个采用经过PCA压缩重建之后的低维特征。
代码语言:javascript复制#对训练数据、测试数据进行特征向量(图片像素)与分类目标的分隔。
x_train = digits_train[np.arange (64)]
y_train = digits_train[64]
x_test = digits_test[np.arange (64) ]
y_test = digits_test[64]
#导入基于线性核的支持向量机分类器。
from sklearn.svm import LinearSVC
#使用默认配置初始化LinearSVC,对原始六十四维像素特征的训练数据进行建模,并在测试数据上做出预测,存储在y_ predict中。
svc = LinearSVC()
svc.fit(x_train, y_train)
y_predict = svc.predict(x_test)
#使用PCA将原六十四维的图像数据压缩到20个维度。
estimator = PCA(n_components = 20)
#利用训练特征决定(fit)20个正交维度的方向,并转化(transform)原训练特征。
pca_x_train = estimator.fit_transform(x_train)
#测试特征也按照上述的20个正交维度方向进行转化(transform)。
pca_x_test = estimator.transform(x_test)
#使用默认配置初始化LinearSVC,对压缩过后的二十维特征的训练数据进行建模,并在测试数据上做出预测,存储在pca_y_ predict中。
pca_svc = LinearSVC()
pca_svc.fit(pca_x_train, y_train)
pca_y_predict = pca_svc.predict(pca_x_test)
性能评测
代码语言:javascript复制#从sklearn.metrics导入classificationreport用于更加细致的分类性能分析。
from sklearn.metrics import classification_report
#对使用原始图像高维像素特征训练的支持向量机分类器的性能作出评估。
print(svc.score(x_test, y_test))
print(classification_report(y_test, y_predict, target_names = np.arange(10).astype (str)))
#对使用PCA压缩重建的低维图像特征训练的支持向量机分类器的性能作出评估。
print(pca_svc.score(pca_x_test, y_test))
print(classification_report(y_test, pca_y_predict, target_names = np.arange(10).astype(str)))
代码语言:javascript复制0.9176405119643851
precision recall f1-score support
0 0.99 0.98 0.98 178
1 0.96 0.84 0.89 182
2 0.99 0.96 0.98 177
3 0.77 0.97 0.86 183
4 0.94 0.97 0.96 181
5 0.91 0.94 0.93 182
6 0.99 0.97 0.98 181
7 0.98 0.91 0.94 179
8 0.87 0.83 0.85 174
9 0.82 0.81 0.82 180
avg / total 0.92 0.92 0.92 1797
0.9170840289371174
precision recall f1-score support
0 0.97 0.98 0.97 178
1 0.79 0.85 0.82 182
2 0.96 0.95 0.96 177
3 0.98 0.89 0.93 183
4 0.95 0.97 0.96 181
5 0.91 0.97 0.94 182
6 0.98 0.96 0.97 181
7 0.97 0.89 0.93 179
8 0.92 0.79 0.85 174
9 0.78 0.92 0.84 180
avg / total 0.92 0.92 0.92 1797
尽管经过PCA特征压缩和重建之后的特征数据会损失2%左右的预测准确性,但是相比于原始数据六十四维度的特征而言,使用PCA压缩并且降低了68.75%的维度。
降维/压缩问题则是选取数据具有代表性的特征,在保持数据多样性的基础上,规避掉大量的特征冗余和噪声,不过这个过程也很有可能会损失一些有用的模式信息。经过大量的实践证明,相较于损失的少部分模型性能,维度压缩能够节省大量用于模型训练的时间。这样一来,使得PCA所带来的模型综合效率变得更为划算。