机器学习系列(二十一)——PCA降噪与人脸识别
PCA实现降噪
仍然以手写识别数据集为例,这次我们使用sklearn中小的手写数字数据集,并为数据集人工加入高斯噪音:
from sklearn import datasets
digits = datasets.load_digits()
X = digits.data
y = digits.target
noisy_digits = X +np.random.normal(0,4,size=X.shape)
接下来将这些加了噪音的数据图像绘制出来,为了可视化方便,0-9每个数字取10个样本,共绘制100个图像:
'''0-9每个样本取10个'''
example_digits = noisy_digits[y==0,:][:10]
for num in range(1,10):
X_num = noisy_digits[y==num,:][:10]
example_digits = np.vstack([example_digits,X_num])
'''手写数字数据可视化函数'''
def plot_digits(data):
fig, axes = plt.subplots(10,10,figsize=(10,10),
subplot_kw={'xticks':[],'yticks':[]},
gridspec_kw=dict(hspace=0.1,wspace=0.1))
for i,ax in enumerate(axes.flat):
ax.imshow(data[i].reshape(8,8),\
cmap='binary',interpolation='nearest',clim=(0,16))
plt.show()
plot_digits(example_digits)
绘制结果如下:
带噪声的数字可视化接下来对数据进行降噪,所谓降噪其实就是提取前k个比较重要的主成分,丢弃原数据集中部分信息而已:
'''降噪'''
pca = PCA(0.5)#目测噪音大,保留0.5信息
pca.fit(noisy_digits)
pca.n_components_ //out:12
这里目测噪声很大,于是丢弃50%的信息,认为它们是噪音,此时数据为12维,再将数据还原为64维,得到的就是降噪之后的数据,并绘制降噪后的图像:
'''去噪音后的特征数据'''
X_components = pca.transform(example_digits)
'''去噪音后恢复64维'''
filtered_digits = pca.inverse_transform(X_components)
plot_digits(filtered_digits)
绘制结果如下:
降噪后数字可视化可以看到,效果比之前好很多。实际中,要丢弃的信息量比例(噪音)要视情况而定,一般来说数据降噪后都会比未降噪的数据表现要好,但也不一定,有些性质较好的数据集降噪确实会损失有用信息。
PCA与人脸识别
在PCA的学习中我们知道,在PCA提取的主成分中,按重要性程度是依次递减的,如果对人脸数据提取主成分后,主成分的每一个向量叫做特征脸。
上面的矩阵X是人脸数据集,Wk是主成分,为什么称Wk的每个向量为特征脸呢?以一个真实的人脸数据集来看一下:
import numpy as np
import matplotlib.pyplot as plt
'''人脸识别数据'''
from sklearn.datasets import fetch_lfw_people
'''导入数据'''
faces = fetch_lfw_people()
faces.keys()
第一次导入数据可能需要下载,而且速度比较慢,这里给出下载好的数据百度云链接,链接: https://pan.baidu.com/s/1MRdDrlFZBAll9svkekUDmg 提取码: 8m9p。下载后将文件拷贝到scikit_learn_data的lfw_home文件夹下即可。
数据基本信息'''随机绘制36个脸'''
random_indexes = np.random.permutation(len(faces.data))
X = faces.data[random_indexes]
example_faces = X[:36,:]
'''绘图函数'''
def plot_faces(faces):
fig, axes = plt.subplots(6,6,figsize=(10,10),subplot_kw={'xticks':[],'yticks':[]},
gridspec_kw=dict(hspace=0.1,wspace=0.1))
for i,ax in enumerate(axes.flat):
ax.imshow(faces[i].reshape(62,47),cmap='bone')
plt.show()
plot_faces(example_faces)
绘制结果:
接下来进行PCA提取主成分并绘制这些主成分:
from sklearn.decomposition import PCA
pca = PCA(svd_solver='randomized')#由于数据多,随机方式求解PCA
pca.fit(X)
'''特征脸'''
plot_faces(pca.components_[:36,:])
绘制结果:
特征脸这就是按照重要程度绘制出来的该数据集的人脸特征,其实也很好理解,人脸识别中第一重要的是人脸的基本轮廓,所以排在前面特征的和人脸轮廓有关,之后特征一步步细化到人脸的一些部位比如眼睛鼻子嘴巴等。一个真实的人脸可以看作这些特征的线性组合。
关于人脸识别还有很多有意思的探索,有兴趣的可以自己在这个数据集上通过机器学习做更多探索。