首先导入人脸数据集和相关的模块:
- from sklearn.datasets import fetch_lfw_people # 人脸数据集
- import matplotlib.pyplot as plt
- from sklearn.decomposition import PCA
- import numpy as np
加载sklearn自带的数据集:
- faces = fetch_lfw_people(min_faces_per_person=60) # min_faces_per_person指定每个人最少有多少张图片
- faces.images.shape # (1348, 62, 47) 1348张图片,每张图片62*47个像素点
- faces.data.shape # (1348, 2914) 1348张图片,每张图片2914个像素点
接下来将数据可视化:
- # 可视化数据
- fig, axes = plt.subplots(3, 8, figsize=(8, 4),subplot_kw={'xticks':[], 'yticks':[]},gridspec_kw=dict(hspace=0.1, wspace=0.1)) # axes是一个子图对象
- for i, ax in enumerate(axes.flat): # axes.flat的作用是将axes转换为一维数组,enumerate的作用是将数组中的元素和索引组成一个元组
- ax.imshow(faces.images[i,:,:], cmap='gray') # cmap指定颜色
- plt.show()
结果如下所示:
接下来我们进行降维操作。我们先对降维过程中生成的新特征空间进行实例化和可视化:
- # 按照特征数量选择降维后的维度
- pca = PCA(n_components=150,svd_solver='auto') # n_components指定降维后的维度,svd_solver指定奇异值分解的方法,包括auto、full、arpack、randomized
- V = pca.fit(faces.data).components_ # 查看新特征空间的属性
- V.shape # (1348, 150) # V是新的特征空间
接下来对新的特征空间进行可视化:
- fig, axes = plt.subplots(3, 8, figsize=(8, 4),subplot_kw={'xticks':[], 'yticks':[]},gridspec_kw=dict(hspace=0.1, wspace=0.1)) # axes是一个子图对象
- for i, ax in enumerate(axes.flat): # axes.flat的作用是将axes转换为一维数组,enumerate的作用是将数组中的元素和索引组成一个元组
- ax.imshow(V[i,:].reshape(62,47), cmap='gray') # cmap指定颜色
- plt.show()
结果如下所示:
由图可知,和降维前的数据相比,新特征空间可视化的数据非常模糊,这是因为原始数据还没有被映射到特征空间中。而且通过对比可以发现,结果有明显的明暗差别,在比较亮的图片中,可以观察到眼睛,鼻子等五官,这说明新的特征空间里的新特征向量们,大多是亮度和五官相关的向量。
为了探究降维后的数据能否恢复到原来的图像,验证降维过程是否有损失,进行如下实验:
-
- x = faces.data
- x.shape # (1348, 2914) 1348张图片,每张图片2914个像素点
- x_dr = pca.fit_transform(x)
- x_dr.shape # (1348, 150) 1348张图片,每张图片150个像素点
- x_inverse = pca.inverse_transform(x_dr)
- x_inverse.shape # (1348, 2914) 1348张图片,每张图片2914个像素点
-
- # 可视化恢复后的数据 不可将降维逆转,因为降维是有损的。只是将数据映射在了原特征空间中
- fig, axes = plt.subplots(2, 10, figsize=(10, 2.5),subplot_kw={'xticks':[], 'yticks':[]},gridspec_kw=dict(hspace=0.1, wspace=0.1)) # axes是一个子图对象
- for i in range(10):
- axes[0,i].imshow(faces.images[i,:,:], cmap='binary_r') # cmap指定颜色
- axes[1,i].imshow(x_inverse[i,:].reshape(62,47), cmap='binary_r') # cmap指定颜色
- plt.show()
实验结果如下:
由图可知,第一行是原图像,第二行是降维后再恢复的图像。可以发现二者有一些细微的差别,恢复后的图像更加模糊一些。降维后数据会有损失,且这种损失是不可逆的。