本文使用matlab采用PCA完成对数据的降维、重构和人脸识别。
参考文章:http://blog.csdn.net/watkinsong/article/details/38536463
我眼中的PCA:
数据的维数过高,处理起来耗时又费力,于是就在想我能不能只处理部分维数,并且得到的结果与全部维数的结果一致。当当当,PCA就出炉了。简单来说,就是一个图片有2000个特征维度,而实际上只有其中100维(甚至更少),对结果的影响起着巨大的作用。
eg:对于皇帝来说,内阁首辅>二辅>三辅>四辅>>其他不知名官员。所以对于皇帝来说,整个内阁所提供的有效治国方略的所占比可以看作是60%,整个文官阶级可以看作是75%,武官阶级20%,平民百姓5%。也就是说虽然老百姓人挺多的,但是提供的治国方案很少,所以认为可以选择性忽略掉他们的提议。再其次,可以忽略武官、文官。。
总结一下就是,我们只关注影响最大的特征维度,放弃掉影响力不足的特征维度。
PCA思路流程如下:
1、减去均值,中心化
2、计算协方差矩阵
3、选取特征值和特征向量
4、训练集转换到特征向量构成的向量空间中完成降维
5、测试集乘以特征向量的转置,再加上去中心化的均值以完成重构
6、识别:选取每个人的一张照片做登记记录,减去均值,乘以降维阵(即特征向量),并将记录集在降维阵中的值记录下来。遍历图片库,并对照片做同样的处理。取图片在降维阵中的值与记录集的值最小欧式距离的图片所属人,为该图片的所属分类。
Matlab代码如下:
%% 读入图片
clear ; close all; clc
%m = 1680; % number of samples
trainset = zeros(10, 50 * 40); % 图片大小 50 * 40
file_path = 'C:\Users\zyfls\Desktop\ML\第五章数据降维\数据\AR\AR\';% 图像文件夹路径
img_path_list = dir(strcat(file_path,'*.bmp'));%获取该文件夹中所有bmp格式的图像
img_num = length(img_path_list);%获取图像总数量
for i = 10: img_num %取出去前十张照片之外做为训练集,前十张作为测试
image_name = img_path_list(i).name;% 图像名
end
%% before training PCA, do feature normalization
mu = mean(trainset);%mean函数用来求 沿数组中不同维的元素的平均值。
trainset_norm = bsxfun(@minus, trainset, mu);%训练集减去平均值
sigma = std(trainset_norm); %std 计算标准差
trainset_norm = bsxfun(@rdivide, trainset_norm, sigma); %trainset_norm 点除 sigma(标准差)
%% we could save the mean face mu to take a look the mean face
imwrite(uint8(reshape(mu, 50, 40)), 'C:\Users\zyfls\Desktop\ML各种截图\5\乱七八糟PCA\meanface.bmp');
fprintf('mean face saved. paused\n');
%% 计算降维阵
X = trainset; % just for convience
[m, n] = size(X);