1PCA的一些基本资料.docx
- 文档编号:5126833
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:20
- 大小:147.93KB
1PCA的一些基本资料.docx
《1PCA的一些基本资料.docx》由会员分享,可在线阅读,更多相关《1PCA的一些基本资料.docx(20页珍藏版)》请在冰豆网上搜索。
1PCA的一些基本资料
PCA降维算法总结以及matlab实现PCA(个人的一点理解)
PCA的一些基本资料
最近因为最人脸表情识别,提取的gabor特征太多了,所以需要用PCA进行对提取的特征进行降维。
本来最早的时候我没有打算对提取的gabor特征进行降维,但是如果一个图像时64*64,那么使用五个尺度八个方向的gabor滤波器进行滤波,这样提取的特征足足有64*64*5*8这么多,如果图像稍微大一点,比如128*128的图像,那么直接提取的特征就会几十万,所以不降维的话直接用SVM训练分类器是非常困难的。
所以在这段时间我就学习了一下PCA降维的基本原理和使用方法,网上给出的资料都比较乱,而且很不清楚,经过这几天的学习和测试,终于把调理弄清楚了,给大家分享一下,下面只是我对于PCA的个人理解,肯定有不对的地方,还请各位大牛多多指教。
具体的PCA的算法的理论基础呢,我这里就不详细说了,因为我也没有看具体详细,所以如果想要彻底的弄明白PCA的工作原来,还是请到wiki上看吧,写的非常清晰,我因为临时用一下,就写个大致的原理就可以了。
PCA原理:
PCA的原理就是将原来的样本数据投影到一个新的空间中,相当于我们在矩阵分析里面学习的将一组矩阵映射到另外的坐标系下。
通过一个转换坐标,也可以理解成把一组坐标转换到另外一组坐标系下,但是在新的坐标系下,表示原来的原本不需要那么多的变量,只需要原来样本的最大的一个线性无关组的特征值对应的空间的坐标即可。
比如,原来的样本是30*1000000的维数,就是说我们有30个样本,每个样本有1000000个特征点,这个特征点太多了,我们需要对这些样本的特征点进行降维。
那么在降维的时候会计算一个原来样本矩阵的协方差矩阵,这里就是1000000*1000000,当然,这个矩阵太大了,计算的时候有其他的方式进行处理,这里只是讲解基本的原理,然后通过这个1000000*1000000的协方差矩阵计算它的特征值和特征向量,最后获得具有最大特征值的特征向量构成转换矩阵。
比如我们的前29个特征值已经能够占到所有特征值的99%以上,那么我们只需要提取前29个特征值对应的特征向量即可。
这样就构成了一个1000000*29的转换矩阵,然后用原来的样本乘以这个转换矩阵,就可以得到原来的样本数据在新的特征空间的对应的坐标。
30*1000000*1000000*29=30*29,这样原来的训练样本每个样本的特征值的个数就降到了29个。
一般来说,PCA降维后的每个样本的特征的维数,不会超过训练样本的个数,因为超出的特征是没有意义的。
下面是XX百科中对pca降维的一段解释,还是挺清晰的:
“对于一个训练集,100个对象模板,特征是10维,那么它可以建立一个100*10的矩阵,作为样本。
求这个样本的协方差矩阵,得到一个10*10的协方差矩阵,然后求出这个协方差矩阵的特征值和特征向量,应该有10个特征值和特征向量,我们根据特征值的大小,取前四个特征值所对应的特征向量,构成一个10*4的矩阵,这个矩阵就是我们要求的特征矩阵,100*10的样本矩阵乘以这个10*4的特征矩阵,就得到了一个100*4的新的降维之后的样本矩阵,每个特征的维数下降了。
当给定一个测试的特征集之后,比如1*10维的特征,乘以上面得到的10*4的特征矩阵,便可以得到一个1*4的特征,用这个特征去分类。
”
我对PCA的一些了解
我的pca迷惑
迷惑一
刚开始接触PCA的时候,咨询了一个浙大的博士朋友,这朋友告诉我,如果对训练样本进行降维,那么样本的数量必须大于特征的维数,然后我当时就迷惑了,那我怎么办啊,我的人脸表情图像顶多有几百张就算多的了,但是每个图像提取的特征的维数将近有几十万,我不可能找那么多样本去啊。
当时有这个迷惑也是因为matlab给出的一个实现在pca降维的函数的说明,就是princomp,这个函数的说明也是用的样本的个数多余特征的维数。
后来经过试验是证实,证实了那个浙大的博士的认识是错误的,pca降维肯定不需要样本的个数大于特征的维数,要不然还降维个什么意思。
比如我有30*1000000的特征矩阵,那么降维后肯定是每个样本在新的空间中的表示的特征维数不超过30.
迷惑二
另外一个迷惑,在最初刚开始做的时候,就是为什么这么大的数据,比如30*1000000直接就降到了30*29,这不是减少的数据有点太多了么,会不会对性能造成影响。
之所以有这个迷惑,是因为最初并不了解pca的工作方式。
pca并不是直接对原来的数据进行删减,而是把原来的数据映射到新的一个特征空间中继续表示,所有新的特征空间如果有29维,那么这29维足以能够表示非常非常多的数据,并没有对原来的数据进行删减,只是把原来的数据映射到新的空间中进行表示,所以你的测试样本也要同样的映射到这个空间中进行表示,这样就要求你保存住这个空间坐标转换矩阵,把测试样本同样的转换到相同的坐标空间中。
有些同学在网上发帖子问对训练样本降维以后,怎么对测试样本降维,是不是还是使用princomp这个函数进行降维,这个是错误的。
如果你要保证程序运行正常,就要保证训练样本和测试样本被映射到同一个特征空间,这样才能保证数据的一致性。
迷惑三
网上有不同的pca降维的代码,每个代码也实现的不一样,那么对于同一个数据是否是pca降维以后都是获得相同的数据呢,也就是说不管你用哪种方式进行pca降维,不管你是从哪里下载到的或者自己根据算法实现的pca降维,同样的矩阵降维以后的数据是否一致?
这个我个人认为,不同的算法最后导致的pca降维的数据肯定不一致。
因为pca降维以后,只是把原来的数据映射到新的特征空间,所以如果你的算法不同,那么选择的协方差矩阵肯定就不同,最后获得的转换矩阵肯定也不一样。
那么训练样本和测试样本和不同的转换矩阵相乘以后最终肯定会获得不同的降维坐标。
所以使用不同的算法应该最后不会有相同的坐标结果,这个也是我一直实验的结果,我也使用了matlab自带的princomp降维,并且使用相同的数据使用网上下载的一些降维方法进行降维,得到的数据都不一致。
比如说princomp这个matlab自带的函数,在降维之前就将每一个样本减去了一个所有样本的平均值,也可能有很多样本没有减去平均值。
princomp这里使用一行表示一个样本,每行包括这个样本的所有的特征值。
而网上大部分都是每一列表示一个样本,这样这一列的所有行都表示这个样本的特征值。
网上的程序使用列表示样本是有一定好处的,比如我的样本是1000000*30,总共有30个训练样本,每个样本的特征值个数是1000000,那么这个矩阵获得的协方差矩阵是30*30,计算起来非常的方便,不想30*1000000这样的矩阵获得到的协方差矩阵式1000000*1000000,直接就内存溢出了,不过matlab有自己的实现方式,巧妙的解决了这个问题。
pca的实现(matlab)
我在网上看了很多pca降维的例子,都大同小异,原理差不多,都是活的原来矩阵的协方差矩阵,然后计算协方差矩阵的特征值和特征向量,最后通过特征向量的根据特征值由大到小的排序进行KL变换神马的获得一个转换矩阵。
1.matlab自带的实现方式
PCA在matlab中的实现举例
以下资料来自matlab的help,翻译和注解部分由笔者添加:
(重点部分添加了翻译!
)
princomp-----函数名称
Principalcomponentanalysis(PCA)ondata
Syntax------函数调用语法
[COEFF,SCORE]=princomp(X)
[COEFF,SCORE,latent]=princomp(X)
[COEFF,SCORE,latent,tsquare]=princomp(X)
[...]=princomp(X,'econ')
Description-----函数描述
COEFF=princomp(X) performsprincipalcomponentsanalysis(PCA)onthen-by-pdatamatrixX,andreturnstheprincipalcomponentcoefficients,alsoknownasloadings.RowsofXcorrespondtoobservations,columnstovariables.COEFFisap-by-pmatrix,eachcolumncontainingcoefficientsforoneprincipalcomponent.Thecolumnsareinorderofdecreasingcomponentvariance.
在n行p列的数据集X上做主成分分析。
返回主成分系数。
X的每行表示一个样本的观测值,每一列表示特征变量。
COEFF是一个p行p列的矩阵,每一列包含一个主成分的系数,列是按主成分变量递减顺序排列。
(按照这个翻译很难理解,其实COEFF是X矩阵所对应的协方差阵V的所有特征向量组成的矩阵,即变换矩阵或称投影矩阵,COEFF每列对应一个特征值的特征向量,列的排列顺序是按特征值的大小递减排序,后面有具体例子解释,见说明1)
princompcentersXbysubtractingoffcolumnmeans,butdoesnotrescalethecolumnsofX.Toperformprincipalcomponentsanalysiswithstandardizedvariables,thatis,basedoncorrelations,useprincomp(zscore(X)).Toperformprincipalcomponentsanalysisdirectlyonacovarianceorcorrelationmatrix,usepcacov.
计算PCA的时候,MATLAB自动对列进行了去均值的操作,但是并不对数据进行规格化,如果要规格化的话,用princomp(zscore(X))。
另外,如果直接有现成的协方差阵,用函数pcacov来计算。
[COEFF,SCORE]=princomp(X) returnsSCORE,theprincipalcomponentscores;thatis,therepresentationofXintheprincipalcomponentspace.RowsofSCOREcorrespondtoobservations,columnstocomponents.
返回的SCORE是对主分的打分,也就是说原X矩阵在主成分空间的表示。
SCORE每行对应样本观测值,每列对应一个主成份(变量),它的行和列的数目和X的行列数目相同。
[COEFF,SCORE,latent]=princomp(X) returnslatent,avectorcontainingtheeigenvaluesofthecovariancematrixofX.
返回的latent是一个向量,它是X所对应的协方差矩阵的特征值向量。
[COEFF,SCORE,latent,tsquare]=princomp(X) returnstsquare,whichcontainsHotelling'sT2statisticforeachdatapoint.
返回的tsquare,是表示对每个样本点Hotelling的T方统计量(我也不很清楚是什么东东)。
Thescoresarethedataformedbytransformingtheoriginaldataintothespaceoftheprincipalcomponents.ThevaluesofthevectorlatentarethevarianceofthecolumnsofSCORE.Hotelling'sT2isameasureofthemultivariatedistanceofeachobservationfromthecenterofthedataset.
所得的分(scores)表示由原数据X转变到主成分空间所得到的数据。
latent向量的值表示SCORE矩阵每列的方差(见说明2)。
Hotelling的T方是用来衡量多变量间的距离,这个距离是指样本观测值到数据集中心的距离。
Whenn<=p,SCORE(:
n:
p)andlatent(n:
p)arenecessarilyzero,andthecolumnsofCOEFF(:
n:
p)definedirectionsthatareorthogonaltoX.
[...]=princomp(X,'econ') returnsonlytheelementsoflatentthatarenotnecessarilyzero,andthecorrespondingcolumnsofCOEFFandSCORE,thatis,whenn<=p,onlythefirstn-1.Thiscanbesignificantlyfasterwhenpismuchlargerthann.
当维数p超过样本个数n的时候,用[...]=princomp(X,'econ')来计算,这样会显著提高计算速度
Examples--举例
(上面说了那么多废话,看了还不一定懂,还不如举例容易理解,下面样本数据集为ingredients,这个数据集是matlab自带的)
ComputeprincipalcomponentsfortheingredientsdataintheHalddataset,andthevarianceaccountedforbyeachcomponent.
loadhald;%载入matlab内部数据
[pc,score,latent,tsquare]=princomp(ingredients);%调用pca分析函数
ingredients,score,pc,latent,tsquare%显示得到的结果
ingredients=
726660
1291552
1156820
1131847
752633
1155922
371176
1312244
2541822
2147426
1402334
1166912
1068812
score=
36.8218-6.8709-4.59090.3967
29.60734.6109-2.2476-0.3958
-12.9818-4.20490.9022-1.1261
23.7147-6.63411.8547-0.3786
-0.5532-4.4617-6.08740.1424
-10.8125-3.64660.9130-0.1350
-32.58828.9798-1.60630.0818
22.606410.72593.23650.3243
-9.26268.9854-0.0169-0.5437
-3.2840-14.15737.04650.3405
9.220012.38613.42830.4352
-25.5849-2.7817-0.38670.4468
-26.9032-2.9310-2.44550.4116
pc=
-0.0678-0.64600.56730.5062
-0.6785-0.0200-0.54400.4933
0.02900.75530.40360.5156
0.7309-0.1085-0.46840.4844
latent=
517.7969
67.4964
12.4054
0.2372
tsquare=
5.6803
3.0758
6.0002
2.6198
3.3681
0.5668
3.4818
3.9794
2.6086
7.4818
4.1830
2.2327
2.7216
%下面我们来做一个验证
%下面为计算ingredients协方差矩阵:
cov_ingredients=cov(ingredients)
cov_ingredients=
34.602620.9231-31.0513-24.1667
20.9231242.1410-13.8782-253.4167
-31.0513-13.878241.02563.1667
-24.1667-253.41673.1667280.1667
%下面为计算ingredients所对应的协方差矩阵(也就是cov_ingredients矩阵)的特征值和特征
%向量,下面的矩阵V为特征向量,D为特征值(对比上面的latent)组成的对角线矩阵
[V,D]=eig(cov_ingredients)
V=
0.50620.56730.6460-0.0678
0.4933-0.54400.0200-0.6785
0.51560.4036-0.75530.0290
0.4844-0.46840.10850.7309
D=
0.2372000
012.405400
0067.49640
000517.7969
%说明1:
对比一下矩阵V和矩阵pc,现在很容易明白为什么COEFF是按列递减顺序排列的
%了!
(V中第三列与pc中倒数第三列差个负号,学过线性代数的人都知道这没问题)
%下面再验证一下说明2
diag(cov(score))
ans=
517.7969
67.4964
12.4054
0.2372
%说明2:
以上结果显示latent确实表示SCORE矩阵每列的方差,517.7969表示第一列方差
下面做图表示结果:
上面说了半天还没有达到我们终极想要的,其实我们要的是由函数[pc,score,latent,tsquare]=princomp(ingredients)它所产生的pc和latent。
由latent可以算出降维后的空间所能表示原空间的程度,只要这个累积的值大于95%就行了。
Thefollowingcommandandplotshowthattwocomponentsaccountfor98%ofthevariance:
cumsum(latent)./sum(latent)
ans=
0.86597
0.97886
0.9996
1
%由以上ans值可以看出前两个主成分就能表示原空间的97.886%,所以取pc中的前两列可
%做主成分变换矩阵tranMatrix=pc(:
1:
2)。
则从原来的4维空间降到2维空间。
对任意一个
%原空间样本,例如a=(7,26,6,60)变到低维空间的表达式为a1=a*tranMatrix。
(当然你也可
%以取pc中的前三列,由原来的4维空间变到3维空间)
biplot(pc(:
1:
2),'Scores',score(:
1:
2),'VarLabels',...
{'X1''X2''X3''X4'})
上面这个matlab函数的说明呢,只是引用XX百科,也可以看看matlab的函数说明,但是多少还是有点难懂。
我把我的理解简单的说说。
[COEFF,SCORE,LATENT,TSQUARED]=PRINCOMP(X)
上面这个函数,coeff矩阵是返回的转换矩阵,也就是把样本转换到新的空间中的准换矩阵,这个准换矩阵式比较大的,比如你的降维矩阵式30*100000,那么这个准换矩阵一般都是10000*29的维数。
score是原来的样本矩阵在新的坐标系中的表示,也就是原来的样本乘上转换矩阵,但是还不是直接乘,要减去一个样本的均值。
将原来的数据转换到新的样本空间中的算法是这样实现的:
x0=bsxfun(@minus,x,mean(x,1));
score=x0*coeff;
然后就会得到和[COEFF,SCORE,LATENT,TSQUARED]=PRINCOMP(X)输出一样的score数据。
同时这个也是原来的样本矩阵降维后的结果,如果使用降维后的数据就使用这个数据。
一般情况下,如果你的每个样本的特征维数远远大于样本数,比如30*1000000的维数,princomp要加上'econ',就是princomp(x,'econ')这样使用,可以很大程度的加快计算速度,而且不会内存溢出,否则会经常报内存溢出。
[...]=PRINCOMP(X,'econ')returnsonlytheelementsofLATENTthatare
notnecessarilyzero,i.e.,whenN<=P,onlythefirstN-1,andthe
correspondingcolumnsofCOEFFandSCORE. Thiscanbesignificantly
fasterwhenP>>N.
latent是返回的按降序排列的特征值,根据这个你可以手动的选择降维以后的数据要选择前多少列。
cumsum(latent)./sum(latent)
,通过这样计算特征值的累计贡献率,一般来说都选择前95%的特征值对应的特征向量,还是原来的矩阵30*1000000,如果你计算得到前25个特征值的累计贡献率已经超过99.9%,那么就完全可以只要降维后的数据的前25列。
tsquared是个什么东西我也不知道。
。
。
不过貌似很少有人能用到,网络上也没有神马资料,各位如果需要用的再查阅吧,一般情况下也用不到。
如果你需要对测试样本降维,一般情况下,使用matlab自带的方式,肯定需要对测试样本减去一个训练样本均值,因为你在给训练样本降维的时候减去了均值,所以测试样本也要减去均值,然后乘以coeff这个矩阵,就获得了测试样本降维后的数据。
比如说你的测试样本是1*1000000,那么乘上一个1000000*29的降维矩阵,就获得了1*29的降维后的测试样本的降维数据。
princomp(x)使用的行表示一个样本,每行的所有的列数据都是这个样本的特征值。
降维以后比如是30*29,那么每
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- PCA 一些 基本资料