赞
踩
http://blog.csdn.net/watkinsong/article/details/8234766
http://blog.csdn.net/mingtian715/article/details/54172281
最近因为最人脸表情识别,提取的gabor特征太多了,所以需要用PCA进行对提取的特征进行降维。
本来最早的时候我没有打算对提取的gabor特征进行降维,但是如果一个图像时64*64,那么使用五个尺度八个方向的gabor滤波器进行滤波,这样提取的特征足足有64*64*5*8这么多,如果图像稍微大一点,比如128*128的图像,那么直接提取的特征就会几十万,所以不降维的话直接用SVM训练分类器是非常困难的。
所以在这段时间我就学习了一下PCA降维的基本原理和使用方法,网上给出的资料都比较乱,而且很不清楚,经过这几天的学习和测试,终于把调理弄清楚了,给大家分享一下,下面只是我对于PCA的个人理解,肯定有不对的地方,还请各位大牛多多指教。
下面先给出一下PCA的资料地址,都是我收集的:
http://hi.baidu.com/yicomrdztxbeiwd/item/913f28c05cf7ebc4994aa06f
http://blog.sciencenet.cn/blog-265205-544681.html
http://blog.csdn.net/mpbchina/article/details/7384425
http://blog.sina.com.cn/s/blog_6833a4df0100pvk7.html
http://stackoverflow.com/questions/4991343/matlab-principal-component-analysis-eigenvalues-order
http://stackoverflow.com/questions/10400230/what-is-score-in-princomp
http://www.mathworks.com/matlabcentral/newsreader/view_thread/152608
http://stats.stackexchange.com/questions/27572/matlab-princomp-latent
http://www.nlpca.org/pca-principal-component-analysis-matlab.html
http://www.matlabsky.com/thread-11751-1-1.html
http://stackoverflow.com/questions/10818718/principal-component-analysis
http://www.mathworks.cn/cn/help/stats/princomp.html
http://www.mathworks.cn/cn/help/stats/pca.html#bti6n7k-2
http://lovelittlebean.blog.163.com/blog/static/116582186201181213911729/
http://www.ilovematlab.cn/thread-54493-1-1.html
http://www.ilovematlab.cn/forum.php?mod=viewthread&tid=146626
http://www.ilovematlab.cn/forum.php?mod=viewthread&tid=204069
http://www.ilovematlab.cn/forum.php?mod=viewthread&tid=54600
http://search.discuz.qq.com/s/aa8585553/princomp+%E9%99%8D%E7%BB%B4.html
http://www.ilovematlab.cn/thread-68796-1-1.html
http://www.ilovematlab.cn/thread-209229-1-1.html
http://www.ilovematlab.cn/thread-209229-1-1.html
http://blog.sina.com.cn/s/blog_61c0518f0100f4mi.html
http://blog.csdn.net/haitao111313/article/details/7875392
http://media.cs.tsinghua.edu.cn/~ahz/digitalimageprocess/chapter11/chapt11_ahz.htm
http://hi.baidu.com/845777018/item/7438e555df1138404fff2011
http://en.wikipedia.org/wiki/Principal_component_analysis
http://baike.baidu.com/view/852194.htm
http://wenku.baidu.com/view/bd9284fcfab069dc51220107.html
http://wenku.baidu.com/view/c0bde56da98271fe910ef9b8.html
http://wenku.baidu.com/view/9f69930790c69ec3d5bb75d3.html
http://www.ilovematlab.cn/thread-54600-1-1.html
http://www.cnblogs.com/sunwufan/archive/2011/08/31/2159952.html
http://zhidao.baidu.com/question/416895922.html
上面的网址都是一些pca原理啊,实现什么的介绍。
具体的PCA的算法的理论基础呢,我这里就不详细说了,因为我也没有看具体详细,所以如果想要彻底的弄明白PCA的工作原来,还是请到wiki上看吧,写的非常清晰,我因为临时用一下,就写个大致的原理就可以了。
PCA的原理就是将原来的样本数据投影到一个新的空间中,相当于我们在矩阵分析里面学习的将一组矩阵映射到另外的坐标系下。通过一个转换坐标,也可以理解成把一组坐标转换到另外一组坐标系下,但是在新的坐标系下,表示原来的原本不需要那么多的变量,只需要原来样本的最大的一个线性无关组的特征值对应的空间的坐标即可。
比如,原来的样本是30*1000000的维数,就是说我们有30个样本,每个样本有1000000个特征点,这个特征点太多了,我们需要对这些样本的特征点进行降维。那么在降维的时候会计算一个原来样本矩阵的协方差矩阵,这里就是1000000*1000000,当然,这个矩阵太大了,计算的时候有其他的方式进行处理,这里只是讲解基本的原理,然后通过这个1000000*1000000的协方差矩阵计算它的特征值和特征向量,最后获得具有最大特征值的特征向量构成转换矩阵。比如我们的前29个特征值已经能够占到所有特征值的99%以上,那么我们只需要提取前29个特征值对应的特征向量即可。这样就构成了一个1000000*29的转换矩阵,然后用原来的样本乘以这个转换矩阵,就可以得到原来的样本数据在新的特征空间的对应的坐标。30*1000000 * 1000000*29 = 30 *29, 这样原来的训练样本每个样本的特征值的个数就降到了29个。
一般来说,PCA降维后的每个样本的特征的维数,不会超过训练样本的个数,因为超出的特征是没有意义的。
下面是百度百科中对pca降维的一段解释,还是挺清晰的:
“对于一个训练集,100个对象模板,特征是10维,那么它可以建立一个100*10的矩阵,作为样本。求这个样本的协方差矩阵,得到一个10*10的协方差矩阵,然后求出这个协方差矩阵的特征值和特征向量,应该有10个特征值和特征向量,我们根据特征值的大小,取前四个特征值所对应的特征向量,构成一个10*4的矩阵,这个矩阵就是我们要求的特征矩阵,100*10的样本矩阵乘以这个10*4的特征矩阵,就得到了一个100*4的新的降维之后的样本矩阵,每个特征的维数下降了。
当给定一个测试的特征集之后,比如1*10维的特征,乘以上面得到的10*4的特征矩阵,便可以得到一个1*4的特征,用这个特征去分类。”
cumsum(latent)./sum(latent),通过这样计算特征值的累计贡献率,一般来说都选择前95%的特征值对应的特征向量,还是原来的矩阵30*1000000,如果你计算得到前25个特征值的累计贡献率已经超过99.9%,那么就完全可以只要降维后的数据的前25列。
得到的均值图像mean_face:
前19个最大主元对应的“特征脸”:
测试:
测试用样本:
四副测试样本的重建误差分别为:
1.4195e+003
1.9564e+003
4.7337e+003
7.0103e+003
可见测试样本为人脸的样本的重建误差显然小于非人脸的重建误差。
最近看了些主成分分析,混迹Matlab论坛,翻了n多帖子,对princomp函数有了些了解。
在此只讲一些个人理解,并没有用术语,只求通俗。
贡献率:每一维数据对于区分整个数据的贡献,贡献率最大的显然是主成分,第二大的是次主成分......
[coef,score,latent,t2] = princomp(x);(个人观点):
x:为要输入的n维原始数据。带入这个matlab自带函数,将会生成新的n维加工后的数据(即score)。此数据与之前的n维原始数据一一对应。
score:生成的n维加工后的数据存在score里。它是对原始数据进行的分析,进而在新的坐标系下获得的数据。他将这n维数据按贡献率由大到小排列。(即在改变坐标系的情况下,又对n维数据排序)
latent:是一维列向量,每一个数据是对应score里相应维的贡献率,因为数据有n维所以列向量有n个数据。由大到小排列(因为score也是按贡献率由大到小排列)。
coef:是系数矩阵。通过cofe可以知道x是怎样转换成score的。
则模型为从原始数据出发:
score= bsxfun(@minus,x,mean(x,1))*coef;(作用:可以把测试数据通过此方法转变为新的坐标系)
逆变换:
x= bsxfun(@plus,score*inv(coef),mean(x,1))
例子:
%% %清屏 clear %% %初始化数据 a=[-14.8271317103068,-3.00108550936016,1.52090778549498,3.95534842970601;-16.2288612441648,-2.80187433749996,-0.410815700402130,1.47546694457079;-15.1242838039605,-2.59871263957451,-0.359965674446737,1.34583763509479;-15.7031424565913,-2.53005662064257,0.255003254103276,-0.179334985754377;-17.7892158910100,-3.32842422986555,0.255791146332054,1.65118282449042;-17.8126324036279,-4.09719527953407,-0.879821957489877,-0.196675865428539;-14.9958877514765,-3.90753364293621,-0.418298866141441,-0.278063876667954;-15.5246706309866,-2.08905845264568,-1.16425848541704,-1.16976057326753;]; x=a; %% %调用princomp函数 [coef,score,latent,t2] = princomp(x); score %测试score是否和score_test一样 score_test=bsxfun(@minus,x,mean(x,1))*coef; score_test latent=100*latent/sum(latent)%将latent总和统一为100,便于观察贡献率 pareto(latent);%调用matla画图
上图是通过自带函数绘制,当贡献率累加至95%,以后的维数会不在显示,最多只显示10维。
下面用自己编写的表示:
之前的错误认识:
1.认为主成分分析中latent显示的贡献值是原始数据的,其实是加工后的数据的。解释:对原始数据既然选择PCA方法,那么计算机认为原始数据每维之间可能存在关联,你想去掉关联、降低维数。所以采用这种方法的。所以计算机并不关心原始数据的贡献值,因为你不会去用了,用的是加工后的数据(这也是为什么当把输入数据每一维的顺序改变后,score、latent不受影响的原因)。
2.认为PCA分析后自动降维,不对。PCA后会有贡献值,是输入者根据自己想要的贡献值进行维数的改变,进而生成数据。(一般大家会取贡献值在85%以上,要求高一点95%)。
3.PCA分析,只根据输入数据的特征进行主成分分析,与输出有多少类型,每个数据对应哪个类型无关。如果样本已经分好类型,那PCA后势必对结果的准确性有一定影响,我认为对于此类数据的PCA,就是在降维与准确性间找一个平衡点的问题,让数据即不会维数多而使运算复杂,又有较高的分辨率。
先说我的结论:降维后维数一定要小于数据样本数
最近在做扭曲图形的识别,思路是用使用一幅静态图像,建立扭曲方程,生成一系列不同形态的扭曲图像,再做Pca降维,生成10个特征基向量,任何一幅扭曲图像都向基向量投影,产生10个特征系数,根据特征系数做识别,其实就是特征脸的过程。
写这篇文章的主要原因是我在网上搜索Pca,发现有一篇文章很火:PCA降维算法总结以及matlab实现PCA(个人的一点理解),被很多人转载,至于我也搞不清原创到底是谁;但不得不说,经过我的思考,我认为这篇文章中有些内容(即样本数目和降维数目关系)是有问题的,特在此讨论一下,希望得到更多人的意见和看法。
首先还是从Matlab中的Pca函数说起
之前自以为对Pca的原理比较清楚,但使用Matlab自带的pca函数时,有些问题困扰了我。下面先介绍一下matlab中pca函数的基本使用:
简单来说,X是n*p矩阵,每一行对应一个样本,每一列对应一个变量,返回值为特征矩阵。
下面实验一下,首先假设X=1024*190,即有1024个样本,数据维数为190:
上面就是把190维数据降到10维的过程,再来看看当X=190*1024时,按理来说此时得到的eff应该是1024*1024,但是:
特征向量矩阵竟然只有1024*189大小,这意味着,当再做降维(投影时),原数据的第二维尺寸肯定小于等于189,即降维尺寸要小于数据样本数!此外,不光是Matlab自带的pca函数,国外常用的机器学习工具箱pca函数(如下)也是要求降维后尺寸小于等于样本数的,感兴趣的可以尝试一下。
X还是n*p数据,no_dims代表需要保留维数或者需要保留的数据差异性(0~1);mappedX是降维后数据,mapping为投影矩阵。
再来说说那篇被广泛转载的博客中:
在我看来,博主应该是理解错他朋友的话了,这句话的想表达的意思应该是降维后数据维数肯定要小于样本数量,而不是降维之前。
当然我这里绝不是吹毛求疵,也不是批评这位博主,只是这个问题的确困扰了我,所以在此提出,希望得到更多讨论。
最后说说为什么降维后数据特征数一定小于样本数?
简单来说,就是确定一直线至少需要两点,确定一平面至少需要三点,确定n维空间至少需要n点。Pca是将原数据投影到新的空间,因此对于样本数n来说,最多确定n维空间。
其实举一个例子就很直观:
上图就是一个将2维数据降维到1维数据的过程,样本数目大于1(降维后维数),可以找到一条直线使得所有点的投影误差和最小,降维过程是有意义的;但如果样本数目不大于1,即只有一个样本,此时降维的过程就意义不大了,因为任取一个过该点的轴都可以使得投影误差最小,即可确定无数子空间。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。