PCA (主成分分析)详解 (写给初学者) 结合matlab

(转载请注明出处)

1、简介 数据库

       PCA(Principal Components Analysis)即主成分分析,是图像处理中常常用到的降维方法,你们知道,咱们在处理有关数字图像处理方面的问题时,好比常常用的图像的查询问题,在一个几万或者几百万甚至更大的数据库中查询一幅相近的图像。这时,咱们一般的方法是对图像库中的图片提取响应的特征,如颜色,纹理,sift,surf,vlad等等特征,而后将其保存,创建响应的数据索引,而后对要查询的图像提取相应的特征,与数据库中的图像特征对比,找出与之最近的图片。这里,若是咱们为了提升查询的准确率,一般会提取一些较为复杂的特征,如sift,surf等,一幅图像有不少个这种特征点,每一个特征点又有一个相应的描述该特征点的128维的向量,设想若是一幅图像有300个这种特征点,那么该幅图像就有300*vector(128维)个,若是咱们数据库中有一百万张图片,这个存储量是至关大的,创建索引也很耗时,若是咱们对每一个向量进行PCA处理,将其降维为64维,是否是很节约存储空间啊?对于学习图像处理的人来讲,都知道PCA是降维的,可是,不少人不知道具体的原理,为此,我写这篇文章,来详细阐述一下PCA及其具体计算过程:网络

2、PCA详解函数

一、原始数据:学习

为了方便,咱们假定数据是二维的,借助网络上的一组数据,以下:
spa

x=[2.5, 0.5, 2.2, 1.9, 3.1, 2.3, 2, 1, 1.5, 1.1]T
y=[2.4, 0.7, 2.9, 2.2, 3.0, 2.7, 1.6, 1.1, 1.6, 0.9]T索引

二、计算协方差矩阵图片

什么是协方差矩阵?相信看这篇文章的人都学过数理统计,一些基本的常识都知道,可是,也许你很长时间不看了,都忘差很少了,为了方便你们更好的理解,这里先简单的回顾一下数理统计的相关知识,固然若是你知道协方差矩阵的求法你能够跳过这里。ip

(1)协方差矩阵:ci

首先咱们给你一个含有n个样本的集合,依次给出数理统计中的一些相关概念:get

均值:
标准差:
方差:

既然咱们都有这么多描述数据之间关系的统计量,为何咱们还要用协方差呢?咱们应该注意到,标准差和方差通常是用来描述一维数据的,但现实生活咱们经常遇到含有多维数据的数据集,最简单的你们上学时免不了要统计多个学科的考试成绩。面对这样的数据集,咱们固然能够按照每一维独立的计算其方差,可是一般咱们还想了解这几科成绩之间的关系,这时,咱们就要用协方差,协方差就是一种用来度量两个随机变量关系的统计量,其定义为:

从协方差的定义上咱们也能够看出一些显而易见的性质,如:

(X的方差)

须要注意的是,协方差也只能处理二维问题,那维数多了天然就须要计算多个协方差,好比n维的数据集就须要计算个协方差,那天然而然的咱们会想到使用矩阵来组织这些数据。给出协方差矩阵的定义:

这个定义仍是很容易理解的,咱们能够举一个简单的三维的例子,假设数据集有三个维度,则协方差矩阵为

可见,协方差矩阵是一个对称的矩阵,并且对角线是各个维度上的方差。

(2)协方差矩阵的求法:

协方差矩阵计算的是不一样维度之间的协方差,而不是不一样样本之间的。下面咱们将在matlab中用一个例子进行详细说明:

首先,随机产生一个10*3维的整数矩阵做为样本集,10为样本的个数,3为样本的维数。
MySample = fix(rand(10,3)*50)

根据公式,计算协方差须要计算均值,那是按行计算均值仍是按列呢,我一开始就总是困扰这个问题。前面咱们也特别强调了,协方差矩阵是计算不一样维度间的协方差,要时刻牢记这一点。样本矩阵的每行是一个样本,每列为一个维度,因此咱们要按列计算均值。为了描述方便,咱们先将三个维度的数据分别赋值:

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 ) % 获得  74.5333
sum( (dim1-mean(dim1)) .* (dim3-mean(dim3)) ) / ( size(MySample,1)-1 ) % 获得  -10.0889
sum( (dim2-mean(dim2)) .* (dim3-mean(dim3)) ) / ( size(MySample,1)-1 ) % 获得  -10***000

搞清楚了这个后面就容易多了,协方差矩阵的对角线就是各个维度上的方差,下面咱们依次计算:

std(dim1)^2 % 获得   108.3222
std(dim2)^2 % 获得   260.6222
std(dim3)^2 % 获得  94.1778

这样,咱们就获得了计算协方差矩阵所须要的全部数据,调用Matlab自带的cov函数进行验证:

cov(MySample)

能够看到跟咱们计算的结果是同样的,说明咱们的计算是正确的。可是一般咱们不用这种方法,而是用下面简化的方法进行计算:

先让样本矩阵中心化,即每一维度减去该维度的均值,而后直接用新的到的样本矩阵乘上它的转置,而后除以(N-1)便可。其实这种方法也是由前面的公式通道而来,只不过理解起来不是很直观而已。你们能够本身写个小的矩阵看一下就明白了。其Matlab代码实现以下:

X = MySample – repmat(mean(MySample),10,1);    % 中心化样本矩阵
C = (X’*X)./(size(X,1)-1)

(为方便对matlab不太明白的人,小小说明一下各个函数,一样,对matlab有必定基础的人直接跳过:

B = repmat(A,m,n ) %%将矩阵 A 复制 m×n 块,即把 A 做为 B 的元素,B 由 m×n 个 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(A)(默认dim=1)就会求每一列的均值
ans =
    3.0000    4.5000    6.0000
用mean(A,2)就会求每一行的均值 
ans =
    2.0000
    4.0000
    6.0000

   6.0000

size(A,n)%% 若是在size函数的输入参数中再添加一项n,并用1或2为n赋值,则 size将返回矩阵的行数或列数。其中r=size(A,1)该语句返回的是矩阵A的行数, c=size(A,2) 该语句返回的是矩阵A的列数)

上面咱们简单说了一下协方差矩阵及其求法,言归正传,咱们用上面简化求法,求出样本的协方差矩阵为:

                      

三、计算协方差矩阵的特征向量和特征值

由于协方差矩阵为方阵,咱们能够计算它的特征向量和特征值,以下:

[eigenvectors,eigenvalues] = eig(cov)

咱们能够看到这些矢量都是单位矢量,也就是它们的长度为1,这对PCA来讲是很重要的。

四、选择成分组成模式矢量

求出协方差矩阵的特征值及特征向量以后,按照特征值由大到小进行排列,这将给出成分的重要性级别。如今,若是你喜欢,能够忽略那些重要性很小的成分,固然这会丢失一些信息,可是若是对应的特征值很小,你不会丢失不少信息。若是你已经忽略了一些成分,那么最后的数据集将有更少的维数,精确地说,若是你的原始数据是n维的,你选择了前p个主要成分,那么你如今的数据将仅有p维。如今咱们要作的是组成一个模式矢量,这只是几个矢量组成的矩阵的一个有意思的名字而已,它由你保持的全部特征矢量构成,每个特征矢量是这个矩阵的一列。

对于咱们的数据集,由于有两个特征矢量,所以咱们有两个选择。咱们能够用两个特征矢量组成模式矢量:

                                     

咱们也能够忽略其中较小特征值的一个特征矢量,从而获得以下模式矢量:

                                                    

五、获得降维后的数据

  

其中rowFeatureVector是由模式矢量做为列组成的矩阵的转置,所以它的行就是原来的模式矢量,并且对应最大特征值的特征矢量在该矩阵的最上一行。rowdataAdjust是每一维数据减去均值后,所组成矩阵的转置,即数据项目在每一列中,每一行是一维,对咱们的样原本说便是,第一行为x维上数据,第二行为y维上的数据。FinalData是最后获得的数据,数据项目在它的列中,维数沿着行。

这将给咱们什么结果呢?这将仅仅给出咱们选择的数据。咱们的原始数据有两个轴(x和y),因此咱们的原始数据按这两个轴分布。咱们能够按任何两个咱们喜欢的轴表示咱们的数据。若是这些轴是正交的,这种表达将是最有效的,这就是特征矢量老是正交的重要性。咱们已经将咱们的数据从原来的xy轴表达变换为如今的单个特征矢量表达。

(说明:若是要恢复原始数据,只需逆过程计算便可,即:

到此为止,相信你已经掌握了PCA及其原理了

相关文章
相关标签/搜索