1、 PCA 降维在 MATLAB 上的实现学 院 计算机科学与技术 专 业 计算机科学与技术 年 级 2011 级 姓 名 周忠儒 /王云标 学 号 30111216058/051 指导教师 魏建国 2014 年 5 月 28 日PCA 降维在 MATLAB 上的实现一 实验目的 .2二 实验环境 .2三 实验原理 .21、PCA 降维方法原理 .22、MATLAB .33、PCA 降维方法详解 .31) 、原始数据: .32)、协方差矩阵的求法: .43)、计算协方差矩阵的特征向量和特征值: .64)、选择成分组成模式矢量: .65)、得到降维后的数据: .7四 实验代码详解 .7五 实验结果
2、 .8六 实验总结 .9PCA 降维在 MATLAB 上的实现一 实验目的1 掌握 PCA 降维的基本内容2 了解 MATLAB 的基本用法3 用 PCA 降维算法处理图像数据 二 实验环境Matlab 7.0三 实验原理1、PCA 降维方法原理PCA 的原理就是将原来的样本数据投影到一个新的空间中,相当于我们在矩阵分析里面学习的将一组矩阵映射到另外的坐标系下。通过一个转换坐标,也可以理解成把一组坐标转换到另外一组坐标系下,但是在新的坐标系下,表示原来的原本不需要那么多的变量,只需要原来样本的最大的一个线性无关组的特征值对应的空间的坐标即可。PCA 即主成分分析,是图像处理中经常用到的降维方法
3、,大家知道,我们在处理有关数字图像处理方面的问题时,比如经常用的图像的查询问题,在一个几万或者几百万甚至更大的数据库中查询一幅相近的图像。这时,我们通常的方法是对图像库中的图片提取响应的特征,如颜色,纹理,sift,surf,vlad 等等特征,然后将其保存,建立响应的数据索引,然后对要查询的图像提取相应的特征,与数据库中的图像特征对比,找出与之最近的图片。2、MATLABMATLAB(矩阵实验室)是 MATrix LABoratory 的缩写,是一款由美国 The MathWorks 公司出品的商业数学软件。MATLAB 是一种用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言
4、和交互式环境。除了矩阵运算、绘制函数/数据图像等常用功能外,MATLAB 还可以用来创建用户界面及与调用其它语言(包括 C,C+和 FORTRAN)编写的程序。3、PCA 降维方法详解1) 、原始数据:由于本实验数据过于庞大,为了方便,我们假定数据是二维的,借助网络上的一组数据,如下:x=2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2, 1, 1.5, 1.1Ty=2.4, 0.7, 2.9, 2.2, 3.0, 2.7, 1.6, 1.1, 1.6, 0.9T2) 、计算协方差矩阵(1)协方差矩阵:以下是含有 n 个样本的集合中,一些数理统计的相关概念:均值:标准差:方差:在
5、这里,标准差和方差一般是用来描述一维数据的,但现实生活我们常常遇到含有多维数据的数据集,例如上学时免不了要统计多个学科的考试成绩。面对这样的数据集,我们当然可以按照每一维独立的计算其方差,但是通常我们还想了解这几科成绩之间的关系,这时,我们就要用协方差,协方差就是一种用来度量两个随机变量关系的统计量,其定义为:从协方差的定义上我们也可以看出一些显而易见的性质,如:1.cov(X,Y)=var(X);2.cov(X,Y)=var(Y,X);需要注意的是,协方差也只能处理二维问题,那维数多了自然就需要计算多个协方差,比如 n 维的数据集就需要计算 个协方差,那自然而然的我们会想到使用矩阵来组织这些
6、数据。给出协方差矩阵的定义:这个定义还是很容易理解的,我们可以举一个简单的三维的例子,假设数据集有三个维度,则协方差矩阵为:可见,协方差矩阵是一个对称的矩阵,而且对角线是各个维度上的方差。2)、协方差矩阵的求法:协方差矩阵计算的是不同维度之间的协方差,而不是不同样本之间的。下面我们将在 matlab 中用一个例子进行详细说明:首先,随机产生一个 10*3 维的整数矩阵作为样本集,10 为样本的个数,3 为样本的维数。MySample = fix(rand(10,3)*50)根据公式,计算协方差需要计算均值,那是按行计算均值还是按列呢,我一开始就老是困扰这个问题。前面我们也特别强调了,协方差矩阵
7、是计算不同维度间的协方差,要时刻牢记这一点。样本矩阵的每行是一个样本,每列为一个维度,所以我们要按列计算均值。为了描述方便,我们先将三个维度的数据分别赋值:dim1 = MySample(:,1);dim2 = MySample(:,2);dim3 = MySample(:,3);计算 dim1 与 dim2,dim1 与 dim3,dim2 与 dim3 的协方差:sum(dim1-mean(dim1).*(dim2-mean(dim2)/(size(MySample,1)-1)sum(dim1-mean(dim1).*(dim3-mean(dim3)/(size(MySample,1)-1
8、) sum(dim2-mean(dim2).*(dim3-mean(dim3)/(size(MySample,1)-1) 搞清楚了这个后面就容易多了,协方差矩阵的对角线就是各个维度上的方差,下面我们依次计算:std(dim1)2 std(dim2)2 std(dim3)2 这样,我们就得到了计算协方差矩阵所需要的所有数据,调用Matlab 自带的 cov 函数进行验证:cov(MySample)可以看到跟我们计算的结果是一样的,说明我们的计算是正确的。但是通常我们不用这种方法,而是用下面简化的方法进行计算:1,先让样本矩阵中心化,即每一维度减去该维度的均值。2,然后直接用新的样本矩阵乘上它的转
9、置。3,然后除以(N-1)即可。其实这种方法也是由前面的公式通道而来,只不过理解起来不是很直观而已。其 Matlab 代码实现如下:X = MySample repmat(mean(MySample),10,1);% 中心化样本矩阵 C = (X*X)./(size(X,1)-1)其中 B=repmat(A,m,n)%将矩阵 A 复制 mn 块。即把 A 作为 B 的元素,B 由 mn 个 A 平铺而成。B 的维数是size(A,1)*m, (size(A,2)*n B = mean(A)的说明:如果你有这样一个矩阵:A = 1 2 3; 3 3 6; 4 6 8; 4 7 7;用 mean(
10、A)(默认 dim=1)就会求每一列的均值 ans = 3.0000 4.5000 6.0000 用 mean(A,2)就会求每一行的均值ans = 2.0000 4.0000 6.0000 6.0000size(A,n)%如果在 size 函数的输入参数中再添加一项 n,并用 1或 2 为 n 赋值,则 size 将返回矩阵的行数或列数。其中r=size(A,1)该语句返回的是矩阵 A 的行数, c=size(A,2) 该语句返回的是矩阵 A 的列数)上面我们简单说了一下协方差矩阵及其求法,言归正传,我们用上面简化求法,求出样本的协方差矩阵为:3)、计算协方差矩阵的特征向量和特征值因为协方差
11、矩阵为方阵,我们可以计算它的特征向量和特征值,如下:eigenvectors,eigenvalues = eig(cov)我们可以看到这些矢量都是单位矢量,也就是它们的长度为 1,这对 PCA 来说是很重要的。4)、选择成分组成模式矢量求出协方差矩阵的特征值及特征向量之后,按照特征值由大到小进行排列,这将给出成分的重要性级别。现在,如果你喜欢,可以忽略那些重要性很小的成分,当然这会丢失一些信息,但是如果对应的特征值很小,你不会丢失很多信息。如果你已经忽略了一些成分,那么最后的数据集将有更少的维数,精确地说,如果你的原始数据是 n 维的,你选择了前 p 个主要成分,那么你现在的数据将仅有 p 维
12、。现在我们要做的是组成一个模式矢量,这只是几个矢量组成的矩阵的一个有意思的名字而已,它由你保持的所有特征矢量构成,每一个特征矢量是这个矩阵的一列。对于我们的数据集,因为有两个特征矢量,因此我们有两个选择。我们可以用两个特征矢量组成模式矢量:我们也可以忽略其中较小特征值的一个特征矢量,从而得到如下模式矢量:5)、得到降维后的数据其中 rowFeatureVector 是由模式矢量作为列组成的矩阵的转置,因此它的行就是原来的模式矢量,而且对应最大特征值的特征矢量在该矩阵的最上一行。rowdataAdjust 是每一维数据减去均值后,所组成矩阵的转置,即数据项目在每一列中,每一行是一维,对我们的样本
13、来说即是,第一行为 x 维上数据,第二行为 y 维上的数据。FinalData 是最后得到的数据,数据项目在它的列中,维数沿着行。这将给我们什么结果呢?这将仅仅给出我们选择的数据。我们的原始数据有两个轴(x 和 y),所以我们的原始数据按这两个轴分布。我们可以按任何两个我们喜欢的轴表示我们的数据。如果这些轴是正交的,这种表达将是最有效的,这就是特征矢量总是正交的重要性。我们已经将我们的数据从原来的 xy 轴表达变换为现在的单个特征矢量表达。说明:如果要恢复原始数据,只需逆过程计算即可,即:四 实验代码详解按照上述 PCA 降维算法的原理编写代码如下:load im.mat将 im 中的数据导入
14、 MATLAB;m = mean(im,2);求 im 数据每一行的平均值,即得数为一列向量,每一元素为 im每一行的平均值。Train_Number = size(im,2);求 im 数据每一行数据的元素个数A = ;定义一个空矩阵 A for i = 1 : Train_Numbertemp = im(:,i) - uint8(m);定义一个中间矩阵变量,其值为 im 中每一列减去 m 的得数A = A temp;将中间矩阵变量 temp 的值存入 A 中endfor 循环的作用是将 im 每一列都减去 m 并存入 A 中L = A*A;L=A 矩阵与其转置矩阵的乘积V D = eig(
15、L);求矩阵 L 的特征值与特征向量L_eig_vec = ;定义一个空矩阵for i = 1 : 15L_eig_vec = L_eig_vec V(:,i);End将特征矩阵存入 L 中PCA = A * L_eig_vec;PCA 为 A 矩阵与特征矩阵的乘积,结果就是降维后的矩阵,为520000 15 维度。五 实验结果最后降至 15 维六 实验总结PCA 降维方法在网上确实有很多的资料,是一种非常常用的处理图像的方法。通过在网上查找资料的过程,不仅了解了 PCA 降维算法,也复习了线性代数这门学科并且更加熟悉了 MATLAB 的用法,获益匪浅。当然在实验过程中也遇到了很多有大有小的问题,比如代码的实现,matlab 的应用,尤其是维度匹配问题研究了好长时间。不过最终都将这些问题一一解决,总之,又学到了好多。