主成分分析(PCA)及其若干应用
主成分分析(PCA)及其若干应用
主成分分析(Principal Component Analysis, PCA)是一种重要的降维方法,在数据压缩、消除冗余和数据噪音消除等领域都有广泛的应用。本文将详细介绍PCA的算法原理、形式化表达以及在数据降维、可视化、图像压缩等领域的应用。
1 背景说明
在机器学习领域,PCA作为一种数据分析算法而闻名。其基本思想是将一组数据的"主要成分"提取出来而忽略剩下的次要内容,达到数据降维的效果,以减少运算资源消耗或达成其他目的。从哲学上讲,这一想法体现了马克思主义哲学中唯物辩证法的核心——矛盾的观点,即抓主要矛盾。
2 算法原理
2.1 PCA简介
PCA试图用数据最主要的若干方面来代替原有的数据,这些最主要的方面首先需要保证蕴含了原始数据中的大量信息,其次需要保证相互之间不相关。因为相关代表了数据在某种程度上的"重叠",也就相当于冗余性没有清除干净。
如上图所示,将二维空间(平面)中的一群离散点投影到一维空间(直线)上去,显然图1(1)的效果比图1(2)好,因为在(2)中点都纠集到了一团,很多点在直线上的投影重合了,这样最多只能保留一个点的信息,而图(1)中的投影相对更加离散。这体现了"方差即信息"的思想。
2.2 基本原理
这里介绍几个将PCA的数学原理写得非常好的博客:
- PCA的数学原理:从简单的2维数据开始讲起,深入浅出、娓娓道来,绝对是教材中的上品,零基础学生的福音;
- Principal Component Analysis:PCA动图展示,支持用户交互,有时候不得不承认,人家老外做的东西就是比国内做得好,而且不止一点半点;
- PCA(主成分分析):这是斯坦福机器学习课程(吴恩达授课)笔记系列的一部分,它最大的价值是针对成机器学习课程形成了一个完整的系列,参考价值很高;
- 機器/統計學習:主成分分析:看上去应该是台湾人做的,示例详实、图文并茂,也很好;
- 主成分分析(PCA)与Kernel PCA:这是一篇包含动图的优质博客,公式不建议深究,KPCA也不完整,但是那张动图确实很好;
- PCA主成分分析学习总结:这是知乎上的一篇学习总结,从基础知识入手,中规中矩,质量较高,而且这个知乎专栏的内容质量也较高。
部分是英文资料,部分资料需要翻墙,这也是没办法的事情。
2.3 形式化表达
将一个问题通过数学方法表达出来,就是形式化表达,这是求解问题的第一步。PCA的形式化表示如下:
这就是PCA的形式化表示,对于一个输入的n行m列矩阵,PCA的目标就是将它降至k维,k<n,输出k行m列矩阵,注意数据量m是保持不变的。
3 算法步骤与代码
PCA算法的实现步骤如下:
有了步骤,接下来就是编程实现。以下是MATLAB代码实现:
function Res = myPCA(X,R,varargin)
%MYPCM - The Principal Component Analysis(PCA) function.
% To calculate the result after PCA, one kind of
% dimension-reduction technical of characteristics.
% Here are some useful reference material:
% https://www.jianshu.com/p/2fad63faa773
% http://blog.codinglabs.org/articles/pca-tutorial.html
%
% Res = myPCA(X,R)
% Res = myPCA(X,R,DIM)
%
% Input -
% X: a N*M matrix containing M datas with N dimensions;
% R: number of dimensions to be reduced to, normally, R<N;
% DIM: specifies a dimension DIM to arrange X.
% DIM = 1: X(N*M)
% DIM = 2: X(M*N)
% DIM = otherwisw: error
% Output -
% Res : the result of PCA of the input matrix X;
% Res.P: a R*N matrix containing R bases with N dimensions;
% Res.Y: a R*M matrix containing M datas with R dimensions;
% Res.contrb: a R*1 vector containing the contribution rate
% of each principal component.
% Res.sumcontrb: a scaler means the sum contribution rate
% of all principal components.
%
% Copyright (c) 2018 CHEN Tianyang
% more info contact: tychen@whu.edu.cn
%% parameter test
% parameter number test
narginchk(2,3);
narg = numel(varargin);
DIM = [];
switch narg
case 0
case 1
DIM = varargin{:};
otherwise
error('Error! Input parameter error.');
end
if isempty(DIM)
DIM = 1;
end
% parameter correction test
if ~ismatrix(X) || ~isreal(R)
error('Error! Input parameters error.');
end
[N,M] = size(X);
if R > N
error('Error! The 2nd parameter should be smaller than the col. of the 1st one.');
elseif R == N
warning('Warning! There is no dimension-reduction effect.');
end
if DIM == 2
X = X';
elseif DIM~=1 && DIM~=2
error('Error! Parameter DIM should be either 1 or 2.');
end
%% core algorithm
center = mean(X,2);
X = X - repmat(center,1,M); % zero_centered for each LINE/Field
C = X*(X')/M; % the Covariance matrix of X, C(N*N)
[eigenvector,eigenvalue] = eig(C);
[B,order] = sort(diag(eigenvalue),'descend');
% calculate contribution-rate matrix
contrb = zeros(R,2);
contrb(:,1) = B(1:R)/sum(B);
for i=1:R
contrb(i,2) = sum(contrb(1:i,1));
end
P = zeros(R,N);
% convert eigenvectors from columns to lines.
for i=1:R
P(i,:) = eigenvector(:,order(i))';
end
Y = P*X;
%% get result
Res.contrb = contrb;
Res.P = P;
Res.Y = Y;
Res.center = center;
end
4 PCA实例与应用
接下来将通过几个实例来检测PCA的性能,并加深理解。
4.1 PCA的实质
PCA的实质是数据的整体旋转。具体来说:
- 尽可能离散就是需要尽可能多地保留原始信息;
- 寻找的方向要相互独立是为了避免保留下来的信息存在冗余;
- "若干个"应当少于、最多等于原始数据维数,否则就不是降维了。
如上图所示,红色为原数据,蓝色为PCA变换后没有降维的数据。可以看见变换后数据质心移到了原点,且根据数据离散程度分别与原坐标系的基底对齐,数据集的形态没有改变(数据点的相对位置不变)。因此,不妨对PCA的原理做如下描述:
将数据整体旋转后,根据数据在各维度上投影的方差值由小到大地舍弃维度。
4.2 用PCA降维
这是PCA最直接的应用,降低了维度就可以减小运算数据量。
4.2.1 语音性别识别数据集
现在用PCA降低语音性别识别实验中所用数据集的维度,该数据集原来的数据维度为20。降维的效果如图所示。
图中蓝、绿、黄三色分别代表总计、男性、女性,柱状图为各主成分的信息贡献率,折线图为前若干主成分的合计信息贡献率。可以发现主成分贡献率逐渐减小而越前面的主成分贡献率越大。一般而言我们需要保留原数据85%以上的信息,在本例中前5个主成分的累计贡献率就达到这一数据,因此理论上可以直接将20维数据降到5维,数据量减少75%而信息量只减少15%。
4.2.2 MNIST数据集
总计20维可能还太小,PCA的效果难以表现出来。现在对MNIST数据集分析,该数据集每一个手写体数字是28*28的矩阵,共计784维。降维的效果如图所示。
图中仅展现了前80维,因为后面的维度基本没有信息。在本例中约前60个主成分的累计贡献率就达到85%,因此理论上可以直接将784维数据降到60+维,数据量减少90%以上而信息量只减少15%。
4.3 用PCA做数据可视化
这一条相当于是4.2的特例,将高维数据降低到2维或是3维,放到坐标系中自然就可视了。图所示是语音数据集的可视化。
图分别为原始数据(20维)被降维到2维和3维后的图像,蓝色是男性数据,红色是女性数据。另一方面,如果降维后两者区分较明显,通过这种方法就可以直接进行分类。
4.4 用PCA做图像压缩
用PCA做图像压缩的基本思路是:
PCA的思路是设矩阵X表示一整一张m行n列的图像,通过矩阵P将其降至k维,得到k行m列矩阵Y。那么反过来,只要知道和Y和P就能计算出矩阵X,而矩阵P和Y的数据量是可以小于矩阵X的。因此,定义保留的数据量与原图像数据量之比为压缩率,则PCA做图像压缩的压缩率为:
在实际处理中,往往是将原图像无重叠拆分成m个子图、每个子图拉成一长度为n的列向量来拼成原矩阵X的。现不妨设一图像长宽都是512像素,则有:
因此:
若将这张图拆分为88的小图,那么n = 64 , m = 4096,根据PCA原理,需满足k <= n,不妨令k = 32,此时原图信息仍能保留绝大部分,而压缩率为50.78%,相当于数据量减少一半而信息几乎不丢失。图所示为用PCA做图像压缩的效果,原图是经典的lena图像,是512在512的灰度图。
上面的图像压缩率是25.391%。
从压缩公式可知,要想进一步压缩,有2条途径可以走:要么减小k,要么使得m和n数值尽可能接近,从而使柯西不等式尽可能接近等号的取值。而要在减小k的同时不止于损失过多的数据,就需要n尽可能小,结果就是m和n的数值差距越来越大,从而偏离柯西不等式的最小值,同时还需记得参与运算的都是整数,且要将图像完整分拆,这些都需要考虑。所以说这是一个trade off的过程,细节部分还需要具体问题具体分析。
另外,若不能将大图完整拆分,也可以考虑给大图补上白边,或是有重叠地拆分,或者所拆分得到的小图也不一定非得是正方形,等等方法都可以尝试。
5 小结
本文初步探讨了主成分分析算法(PCA)的原理以及若干应用,下面做一个小结。
PCA是一种著名的数据降维算法,它应用的条件是数据/特征之间具有明显的线性相关性,它的两个主要的指导思想是抓主要矛盾和方差即信息,它的基本应用是数据降维,以此为基础还有数据可视化、数据压缩存储、异常检测、特征匹配与距离计算等。从数学上理解,它是一种矩阵分解算法;从物理意义上理解,它是线性空间上的线性变换。
PCA的核心代码已经在文中给出,其他的都是一些测试代码,这里就不给出了。关于PCA,还有KPCA(Kernel PCA,核PCA)、MPCA(Multilinear PCA,多线性PCA)等变形,可以有效弥补标准PCA算法存在的某种缺陷,关于这些内容,会在后续的文章中简要介绍。