大数据,机器学习,人工智能人工智能/模式识别/机器学习精华专题机器学习、深度学习与人工智能

机器学习系列(二十一)——PCA降噪与人脸识别

2019-07-15  本文已影响1人  Ice_spring

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= \begin{pmatrix} X_{1}^{(1)} , X_{2}^{(1)},...,X_{n}^{(1)}\\X_{1}^{(2)} ,X_{2}^{(2)},...,X_{n}^{(2)}\\...\\X_{1}^{(m)} , X_{2}^{(m)},...,X_{n}^{(m)} \end{pmatrix} , W_{k}= \begin{pmatrix} W_{1}^{(1)} , W_{2}^{(1)},...,W_{n}^{(1)}\\W_{1}^{(2)} ,W_{2}^{(2)},...,W_{n}^{(2)}\\...\\W_{1}^{(k)} , W_{2}^{(k)},...,W_{n}^{(k)} \end{pmatrix}

上面的矩阵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,:])

绘制结果:

特征脸

这就是按照重要程度绘制出来的该数据集的人脸特征,其实也很好理解,人脸识别中第一重要的是人脸的基本轮廓,所以排在前面特征的和人脸轮廓有关,之后特征一步步细化到人脸的一些部位比如眼睛鼻子嘴巴等。一个真实的人脸可以看作这些特征的线性组合。
关于人脸识别还有很多有意思的探索,有兴趣的可以自己在这个数据集上通过机器学习做更多探索。

上一篇下一篇

猜你喜欢

热点阅读