基于PCA的人脸识别系统(JAVA版)(二) PCA原理介绍

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_28352753/article/details/78775799

         前面一篇博客介绍了JAVA环境上怎么配置OpenCV。这篇简单介绍了一下PCA的原理,并且在Matlab和Python上分别进行了编码实现。

  1 PCA原理

主成分分析  Principal ComponentAnalysis PCA)或者主元分析。计算主成分的目的是将高维数据投影到较低维空间

  PCA是基于原始数据空间, 通过
  • 构造一组新的潜隐变量来降低原始数据空间的
 维数
  • 再从新的映射空间抽取主要变化信息,提取统
 计特征
  • 从而构成对原始数据空间特性的理解。

从线性代数角度来看,PCA目标是找到一组新正交基去重新描述得到的数据空间,这个维度就是主元

        PCA的主要步骤如下:

          1.去除平均值,归一化

          2.计算协方差矩阵的特征值和特征向量

          3.将特征值从大道小排序,取前N个特征向量

          4.将数据转换到上述N个特征向量构建的新空间中

     2 Matlab程序

%% PCA Demo  write by jianglei 2017.12.11
%% 加载数据
fileName='testSet.txt';
data=load(fileName);
%% PCA运算
meanVal=mean(data);
trainNum=size(data,1);
%% 去均值
meanRemoved=[];
for i=1:trainNum
    temp=data(i,:)-meanVal;
    meanRemoved=[meanRemoved;temp];
end
%% 计算协方差矩阵和特征值特征向量
covMat=cov(meanRemoved);
[eigVects,eigVals]=eig(covMat);
onesMat=ones(size(eigVals,1),1);
eigValToVert=eigVals*onesMat;%将特征值得特征向量转化为列向量
eigValToVert=sort(eigValToVert,'descend');%降序排序
N=1;
eigValToVert=eigValToVert(1:N);%取前N个特征
exctEigVect=[];
for i=1:size(eigValToVert,1)
    for j=1:size(eigVals,1)
      if(eigValToVert(i)==eigVals(j,j))
       exctEigVect=[exctEigVect;eigVects(:,j)];
      end 
    end 
    if(i>N)  %已经找到了前N个特征值得特征向量,退出循环
       break;
    end
end 
%% 转换到低维空间,以提取的特征向量为基底,实现降维
lowDataMat=meanRemoved*exctEigVect;
reconMat=[];
temp=lowDataMat*exctEigVect';
for i=1:trainNum 
    reconMat=[reconMat;temp(i,:)+meanVal];
end
%%  降维结果显示
figure();
plot(data(:,1),data(:,2),'b*');
hold on
plot(reconMat(:,1),reconMat(:,2),'ro');
hold off


    3 Python程序

from numpy import *
import matplotlib.pyplot as plt
#coding=utf-8

#读入数据文件
def loadDataSet(fileName,delim='\t'):
	fr = open(fileName)
	stringArr = [line.strip().split(delim) for line in fr.readlines()]
	datArr = [list(map(float,line)) for line in stringArr]
	return mat(datArr)

#PCA运算 topNfeat = 9999999可选参数,即应用N个特征。不指定才采取全部特征
def pca(dataMat,topNfeat = 9999999):
	#去均值
	meanVal = mean(dataMat,axis=0)
	meanRemoved = dataMat-meanVal
	#计算协方差矩阵的特征值特征向量
	covMat = cov(meanRemoved,rowvar=0)
	eigVals,eigVects = linalg.eig(covMat)
	eigValsInd = argsort(eigVals)
	eigValsInd = eigValsInd[:-(topNfeat):-1]#取后面的topNfeat个数,但是不包括-topNfeat
	redEigVects=eigVects[:,eigValsInd]
	lowDataMat=meanRemoved*redEigVects
	reconMat=(lowDataMat * redEigVects.T)+meanVal
	return lowDataMat,reconMat
#显示结果
def showResoult(dataMat,reconsMat):
	fig=plt.figure();
	fig.add_subplot(111);
	plt.plot(dataMat[:,0],dataMat[:,1],'b*');
	plt.plot(reconsMat[:,0],reconsMat[:,1],'ro');
	plt.show()
	
datasMat=loadDataSet('testSet.txt')
lowData,reconsMat=pca(datasMat,2)
shape(lowData)
showResoult(datasMat,reconsMat)


没有更多推荐了,返回首页