pca降维 图像处理_pca 图像降维 - CSDN
  • 学习图像处理,无疑会涉及到降维的操作,而PCA是常用的降维算法,既然经常用到,所以需要抠明白才行啊~~  PCA(PrincipalComponents Analysis)即主成分分析,是图像处理中经常用到的降维方法,大家知道,我们在...

        学习图像处理,无疑会涉及到降维的操作,而PCA是常用的降维算法,既然经常用到,所以需要抠明白才行啊~~

          PCA(PrincipalComponents Analysis)即主成分分析,是图像处理中经常用到的降维方法,大家知道,我们在处理有关数字图像处理方面的问题时,比如经常用的图像的查询问题,在一个几万或者几百万甚至更大的数据库中查询一幅相近的图像。

        这时,我们通常的方法是对图像库中的图片提取响应的特征,如颜色,纹理,sift,surf,vlad等特征,然后将其保存,建立响应的数据索引,然后对要查询的图像提取相应的特征,与数据库中的图像特征对比,找出与之最近的图片。

        这里,如果我们为了提高查询的准确率,通常会提取一些较为复杂的特征,如sift,surf等,一幅图像有很多个这种特征点,每个特征点又有一个相应的描述该特征点的128维的向量,设想如果一幅图像有300个这种特征点,那么该幅图像就有300*vector(128维)个,如果我们数据库中有一百万张图片,这个存储量是相当大的,建立索引也很耗时如果我们对每个向量进行PCA处理,将其降维为64维,是不是很节约存储空间啊?

        发现一篇对PCA的原理介绍很详细易懂的文章,附上链接供需要者查看,~~

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



    展开全文
  • 降维概念 机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x...目前大部分降维算法处理向量表达的数据,也有一些降维算法处理高阶...

    降维概念
    机器学习领域中所谓的降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。降维的本质是学习一个映射函数 f : x->y,其中x是原始数据点的表达,目前最多使用向量表达形式。 y是数据点映射后的低维向量表达,通常y的维度小于x的维度(当然提高维度也是可以的)。f可能是显式的或隐式的、线性的或非线性的。
    目前大部分降维算法处理向量表达的数据,也有一些降维算法处理高阶张量表达的数据。之所以使用降维后的数据表示是因为在原始的高维空间中,包含有冗余信息以及噪音信息,在实际应用例如图像识别中造成了误差,降低了准确率;而通过降维,我们希望减少冗余信息所造成的误差,提高识别(或其他应用)的精度。又或者希望通过降维算法来寻找数据内部的本质结构特征。
    在很多算法中,降维算法成为了数据预处理的一部分,如PCA。事实上,有一些算法如果没有降维预处理,其实是很难得到很好的效果的。
    对原始数据采取降维的原因通常有两个:① 缓解“维度灾难” ② 对数据进行可视化。
      降维的好坏没有一个直接的标准(包括上面提到的重构误差也只能作为一个中性的指标)。通常通过对数据进行降维,然后用降维后的数据进行学习,再根据学习的效果选择一个恰当的降维方式和一个合适的降维模型参数。 
    一、关于参数
    n_components:
    意义:PCA算法中所要保留的主成分个数n,也即保留下来的特征个数n
    类型:int 或者 string,缺省时默认为None,所有成分被保留。
    赋值为int,比如n_components=1,将把原始数据降到一个维度。
    赋值为string,比如n_components=‘mle’,将自动选取特征个数n,使得满足所要求的方差百分比。

    copy: 类型:bool,True或者False,缺省时默认为True。
    意义:表示是否在运行算法时,将原始训练数据复制一份。若为True,则运行PCA算法后,原始训练数据的值不会有任何改变,因为是在原始数据的副本上进行运算;若为False,则运行PCA算法后,原始训练数据的值会改,因为是在原始数据上进行降维计算。
    whiten: 类型:bool,缺省时默认为False ; 意义:白化。
    二、PCA对象属性
    components_:返回具有最大方差的成分。
    explained_variance_ratio_:返回 所保留的n个成分各自的方差百分比。
    n_components_:返回所保留的成分个数n。
    三、PCA对象属性
    fit(X,y=None)
    fit()可以说是scikit-learn中通用的方法,每个需要训练的算法都会有fit()方法,它其实就是算法中的“训练”这一步骤。因为PCA是无监督学习算法,此处y自然等于None。
    fit(X):表示用数据X来训练PCA模型。
    函数返回值:调用fit方法的对象本身。比如pca.fit(X),表示用X对pca这个对象进行训练。
    fit_transform(X)
    用X来训练PCA模型,同时返回降维后的数据。
    newX=pca.fit_transform(X),newX就是降维后的数据。

    inverse_transform()
    将降维后的数据转换成原始数据,
    X=pca.inverse_transform(newX)

    transform(X)
    将数据X转换成降维后的数据。当模型训练好后,对于新输入的数据,都可以用transform方法来降维。

    下图是对东莞部分数据降维实例(使用PCA降维前要对数据做标准化处理),仅供参考:
    在这里插入图片描述
    下图是降维后特征重要性分布图(数据降维后特征会失真):
    在这里插入图片描述

    展开全文
  • python实现PCA降维

    2018-10-08 15:20:52
    本文主要介绍一种降维方法,PCA(Principal Component Analysis,主成分分析)。降维致力于解决三类问题。 1. 降维可以缓解维度灾难问题; 2. 降维可以在压缩数据的同时让信息损失最小化; 3. 理解几百个维度的数据...

    概述

    本文主要介绍一种降维方法,PCA(Principal Component Analysis,主成分分析)。降维致力于解决三类问题。
    1. 降维可以缓解维度灾难问题;
    2. 降维可以在压缩数据的同时让信息损失最小化;
    3. 理解几百个维度的数据结构很困难,两三个维度的数据通过可视化更容易理解。

    PCA简介

    在理解特征提取与处理时,涉及高维特征向量的问题往往容易陷入维度灾难。随着数据集维度的增加,算法学习需要的样本数量呈指数级增加。有些应用中,遇到这样的大数据是非常不利的,而且从大数据集中学习需要更多的内存和处理能力。另外,随着维度的增加,数据的稀疏性会越来越高。在高维向量空间中探索同样的数据集比在同样稀疏的数据集中探索更加困难。
    主成分分析也称为卡尔胡宁-勒夫变换(Karhunen-Loeve Transform),是一种用于探索高维数据结构的技术。PCA通常用于高维数据集的探索与可视化。还可以用于数据压缩,数据预处理等。PCA可以把可能具有相关性的高维变量合成线性无关的低维变量,称为主成分( principal components)。新的低维数据集会尽可能的保留原始数据的变量。
    PCA将数据投射到一个低维子空间实现降维。例如,二维数据集降维就是把点投射成一条线,数据集的每个样本都可以用一个值表示,不需要两个值。三维数据集可以降成二维,就是把变量映射成一个平面。一般情况下,nn维数据集可以通过映射降成kk维子空间,其中k≤nk≤n。
    假如你是一本养花工具宣传册的摄影师,你正在拍摄一个水壶。水壶是三维的,但是照片是二维的,为了更全面的把水壶展示给客户,你需要从不同角度拍几张图片。下图是你从四个方向拍的照片:
    wateringcan.png
    第一张图里水壶的背面可以看到,但是看不到前面。第二张图是拍前面,可以看到壶嘴,这张图可以提供了第一张图缺失的信息,但是壶把看不到了。从第三张俯视图里无法看出壶的高度。第四张图是你真正想要的,水壶的高度,顶部,壶嘴和壶把都清晰可见。
    PCA的设计理念与此类似,它可以将高维数据集映射到低维空间的同时,尽可能的保留更多变量。PCA旋转数据集与其主成分对齐,将最多的变量保留到第一主成分中。假设我们有下图所示的数据集:
    dataset.png
    数据集看起来像一个从原点到右上角延伸的细长扁平的椭圆。要降低整个数据集的维度,我们必须把点映射成一条线。下图中的两条线都是数据集可以映射的,映射到哪条线样本变化最大?
    datasetline.png
    显然,样本映射到黑色虚线的变化比映射到红色点线的变化要大的多。实际上,这条黑色虚线就是第一主成分。第二主成分必须与第一主成分正交,也就是说第二主成分必须是在统计学上独立的,会出现在与第一主成分垂直的方向,如下图所示:
    orthogonal.png
    后面的每个主成分也会尽量多的保留剩下的变量,唯一的要求就是每一个主成分需要和前面的主成分正交。
    现在假设数据集是三维的,散点图看起来像是沿着一个轴旋转的圆盘。
    threedimensional.png
    这些点可以通过旋转和变换使圆盘完全变成二维的。现在这些点看着像一个椭圆,第三维上基本没有变量,可以被忽略。
    当数据集不同维度上的方差分布不均匀的时候,PCA最有用。(如果是一个球壳形数据集,PCA不能有效的发挥作用,因为各个方向上的方差都相等;没有丢失大量的信息维度一个都不能忽略)。

    python实现PCA降维代码

    # coding=utf-8
    from sklearn.decomposition import PCA  
    from pandas.core.frame import DataFrame
    import pandas as pd  
    import numpy as np  
    l=[]
    with open('test.csv','r') as fd:
      
        line= fd.readline()
        while line:
            if line =="":
                continue
      
            line = line.strip()
            word = line.split(",")
            l.append(word)
            line= fd.readline()
    
    data_l=DataFrame(l)
    print (data_l)
    dataMat = np.array(data_l)  
    
    
    pca_sk = PCA(n_components=2)  
    newMat = pca_sk.fit_transform(dataMat)  
     
    
    data1 = DataFrame(newMat)
    data1.to_csv('test_PCA.csv',index=False,header=False)
    
    
    

    展开全文
  • 工具:matlab,本人使用的是2016a ...matlab中内含了进行PCA降维的函数,但这个函数输进去的数据要是二维的,所以我们先用resharp函数把原矩阵处理成111104*204的矩阵M 再使用自带的降维函数: [pc,score,latent...

    工具:matlab,本人使用的是2016a
    使用数据集用公开的Salinas数据集为例,Salinas数据集为512*217*204,即它有204个波段,我们要把它从204维降至3维。

    matlab中内含了进行PCA降维的函数,但这个函数输进去的数据要是二维的,所以我们先用resharp函数把原矩阵处理成111104*204的矩阵M
    再使用自带的降维函数:
    [pc,score,latent,tsquare] = pca(M)

    latent用来计算降维后取多少维度能够达到自己需要的精度,
    通过下面的代码运行结果可以得到取pc中对应每一维度对原始数据的精度:
    在命令行输入
    cumsum(latent)./sum(latent)
    部分截如下

    我们可以看到只去取第一维的话和原始数据的准确度只有74.4%,我们取到第三维,此时已有99%的精度,一般来说取到90%以上即可。

    再取前三维,把矩阵还原为三维。此时便已完成了对高光谱图像的降维。

    完整代码如下:
    M=reshape(d,111104,204);
    [pc,score,latent,tsquare] = pca(M);
    feature_after_PCA=score(:,1:3);
    RES=reshape(feature_after_PCA,512,217,3);

    导入进来的矩阵命名为d

    把它转为图片看看效果:
    imwrite(RES(:,:,1),’1.jpg’);
    这里写图片描述

    这里写图片描述

    这里写图片描述

    展开全文
  • http://blog.csdn.net/watkinsong/article/details/8234766 ... PCA的一些基本资料 最近因为最人脸表情识别,提取的gabor特征太多了,所以需要用PCA进行对提取的特征进行降维

    http://blog.csdn.net/watkinsong/article/details/8234766

    http://blog.csdn.net/mingtian715/article/details/54172281



    PCA的一些基本资料

    最近因为最人脸表情识别,提取的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原理:


    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的特征,用这个特征去分类。


    我对 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-----函数名称
      Principal component analysis (PCA) on data
      Syntax------函数调用语法
      [COEFF,SCORE] = princomp(X)
      [COEFF,SCORE,latent] = princomp(X)
      [COEFF,SCORE,latent,tsquare] = princomp(X)
      [...] = princomp(X,'econ')
      Description -----函数描述
      COEFF = princomp(X) performs principal components analysis (PCA) on the n-by-p data matrix X, and returns the principal component coefficients, also known as loadings. Rows of X correspond to observations, columns to variables. COEFF is a p-by-p matrix, each column containing coefficients for one principal component. The columns are in order of decreasing component variance.
      在n行p列的数据集X上做主成分分析。返回主成分系数。X的每行表示一个样本的观测值,每一列表示特征变量。COEFF是一个p行p列的矩阵,每一列包含一个主成分的系数,列是按主成分变量递减顺序排列。(按照这个翻译很难理解,其实COEFF是X矩阵所对应的协方差阵V的所有特征向量组成的矩阵,即变换矩阵或称投影矩阵,COEFF每列对应一个特征值的特征向量,列的排列顺序是按特征值的大小递减排序,后面有具体例子解释,见说明1)
      princomp centers X by subtracting off column means, but does not rescale the columns of X. To perform principal components analysis with standardized variables, that is, based on correlations, use princomp(zscore(X)). To perform principal components analysis directly on a covariance or correlation matrix, use pcacov.
      计算PCA的时候,MATLAB自动对列进行了去均值的操作,但是并不对数据进行规格化,如果要规格化的话,用princomp(zscore(X))。另外,如果直接有现成的协方差阵,用函数pcacov来计算。
      [COEFF,SCORE] = princomp(X) returns SCORE, the principal component scores; that is, the representation of X in the principal component space. Rows of SCORE correspond to observations, columns to components.
      返回的SCORE是对主分的打分,也就是说原X矩阵在主成分空间的表示。SCORE每行对应样本观测值,每列对应一个主成份(变量),它的行和列的数目和X的行列数目相同。
      [COEFF,SCORE,latent] = princomp(X) returns latent, a vector containing the eigenvalues of the covariance matrix of X.
      返回的latent是一个向量,它是X所对应的协方差矩阵的特征值向量。
      [COEFF,SCORE,latent,tsquare] = princomp(X) returns tsquare, which contains Hotelling's T2 statistic for each data point.
      返回的tsquare,是表示对每个样本点Hotelling的T方统计量(我也不很清楚是什么东东)。
      The scores are the data formed by transforming the original data into the space of the principal components. The values of the vector latent are the variance of the columns of SCORE. Hotelling's T2 is a measure of the multivariate distance of each observation from the center of the data set.
      所得的分(scores)表示由原数据X转变到主成分空间所得到的数据。latent向量的值表示SCORE矩阵每列的方差(见说明2)。Hotelling的T方是用来衡量多变量间的距离,这个距离是指样本观测值到数据集中心的距离。
      When n <= p, SCORE(:,n:p) and latent(n:p) are necessarily zero, and the columns of COEFF(:,n:p) define directions that are orthogonal to X.
      [...] = princomp(X,'econ') returns only the elements of latent that are not necessarily zero, and the corresponding columns of COEFF and SCORE, that is, when n <= p, only the first n-1. This can be significantly faster when p is much larger than n.
      当维数p超过样本个数n的时候,用[...] = princomp(X,'econ')来计算,这样会显著提高计算速度
      Examples--举例
      (上面说了那么多废话,看了还不一定懂,还不如举例容易理解,下面样本数据集为ingredients,这个数据集是matlab自带的)
      Compute principal components for the ingredients data in the Hald data set, and the variance accounted for by each component.
      load hald; %载入matlab内部数据
      [pc,score,latent,tsquare] = princomp(ingredients); %调用pca分析函数
      ingredients,score,pc,latent,tsquare %显示得到的结果
      ingredients =
      7 26 6 60
      1 29 15 52
      11 56 8 20
      11 31 8 47
      7 52 6 33
      11 55 9 22
      3 71 17 6
      1 31 22 44
      2 54 18 22
      21 47 4 26
      1 40 23 34
      11 66 9 12
      10 68 8 12
      score =
      36.8218 -6.8709 -4.5909 0.3967
      29.6073 4.6109 -2.2476 -0.3958
      -12.9818 -4.2049 0.9022 -1.1261
      23.7147 -6.6341 1.8547 -0.3786
      -0.5532 -4.4617 -6.0874 0.1424
      -10.8125 -3.6466 0.9130 -0.1350
      -32.5882 8.9798 -1.6063 0.0818
      22.6064 10.7259 3.2365 0.3243
      -9.2626 8.9854 -0.0169 -0.5437
      -3.2840 -14.1573 7.0465 0.3405
      9.2200 12.3861 3.4283 0.4352
      -25.5849 -2.7817 -0.3867 0.4468
      -26.9032 -2.9310 -2.4455 0.4116
      pc =
      -0.0678 -0.6460 0.5673 0.5062
      -0.6785 -0.0200 -0.5440 0.4933
      0.0290 0.7553 0.4036 0.5156
      0.7309 -0.1085 -0.4684 0.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.6026 20.9231 -31.0513 -24.1667
      20.9231 242.1410 -13.8782 -253.4167
      -31.0513 -13.8782 41.0256 3.1667
      -24.1667 -253.4167 3.1667 280.1667
      %下面为计算ingredients所对应的协方差矩阵(也就是cov_ingredients矩阵)的特征值和特征
      %向量,下面的矩阵V为特征向量,D为特征值(对比上面的latent)组成的对角线矩阵
      [V,D] = eig(cov_ingredients)
      V =
      0.5062 0.5673 0.6460 -0.0678
      0.4933 -0.5440 0.0200 -0.6785
      0.5156 0.4036 -0.7553 0.0290
      0.4844 -0.4684 0.1085 0.7309
      D =
      0.2372 0 0 0
      0 12.4054 0 0
      0 0 67.4964 0
      0 0 0 517.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%就行了。
      The following command and plot show that two components account for 98% of the variance:
      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函数的说明呢,只是引用百度百科,也可以看看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') returns only the elements of LATENT that are
    not necessarily zero, i.e., when N <= P, only the first N-1, and the
    corresponding columns of COEFF and SCORE. This can be significantly
    faster when P >> 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,那么每一行就是降维以后的数据。每个样本有29个特征值。


    2. 一个自实现的pca降维方式


    下面是来自mpb同学的一个自实现的例子,很牛的一个人,我们本科同学。
    原文地址:http://blog.csdn.net/mpbchina/article/details/7384425

    下面引用原文内容:
    1. %训练
    2. %Lx=X'*X
    3. clear;
    4. clc;
    5. train_path='..\Data\TrainingSet\';
    6. phi=zeros(64*64,20);
    7. for i=1:20
    8. path=strcat(train_path,num2str(i),'.bmp');
    9. Image=imread(path);
    10. Image=imresize(Image,[64,64]);
    11. phi(:,i)=double(reshape(Image,1,[])');
    12. end;
    13. %mean
    14. mean_phi=mean(phi,2);
    15. mean_face=reshape(mean_phi,64,64);
    16. Image_mean=mat2gray(mean_face);
    17. imwrite(Image_mean,'meanface.bmp','bmp');
    18. %demean
    19. for i=1:19
    20. X(:,i)=phi(:,i)-mean_phi;
    21. end
    22. Lx=X'*X;
    23. tic;
    24. [eigenvector,eigenvalue]=eigs(Lx,19);
    25. toc;
    26. %normalization
    27. for i=1:19
    28. %K-L变换
    29. UL(:,i)=X*eigenvector(:,i)/sqrt(eigenvalue(i,i));
    30. end
    31. %display Eigenface
    32. for i=1:19
    33. Eigenface=reshape(UL(:,i),[64,64]);
    34. figure(i);
    35. imshow(mat2gray(Eigenface));
    36. end

    得到的均值图像mean_face:

    前19个最大主元对应的“特征脸”

    测试
    测试用样本:

    [plain] view plaincopy
    1. %使用测试样本进行测试
    2. clc;
    3. test_path='..\Data\TestingSet\';
    4. error=zeros([1,4]);
    5. for i=1:4
    6. path=strcat(test_path,num2str(i),'.bmp');
    7. Image=imread(path);
    8. Image=double(imresize(Image,[64,64]));
    9. phi_test=zeros(64*64,1);
    10. phi_test(:,1)=double(reshape(Image,1,[])');
    11. X_test=phi_test-mean_phi;
    12. Y_test=UL'*X_test;
    13. X_test_re=UL*Y_test;
    14. Face_re=X_test_re+mean_phi;
    15. calculate error rate
    16. e=Face_re-phi_test;
    17. %%display figure
    18. Face_re_2=reshape(Face_re(:,1),[64,64]);
    19. figure(i);
    20. imshow(mat2gray(Image));
    21. title('Original');
    22. figure(10+i);
    23. imshow(mat2gray(Face_re_2));
    24. title('Reconstruct');
    25. error(1,i)=norm(e);
    26. %dispaly error rate
    27. error_rate=error(1,i);
    28. display(error_rate);
    29. end
    重建出的测试样本与原样本的对比:

    四副测试样本的重建误差分别为:
    1.4195e+003
    1.9564e+003
    4.7337e+003
    7.0103e+003

    可见测试样本为人脸的样本的重建误差显然小于非人脸的重建误差。


    上面的降维的例子中,每一列表示一个样本,这样就一共有4096*20的待降维矩阵,然后对这个矩阵降维,请注意,如果采用列表示一个样本,那么获得的降维矩阵,是一个4096*19的矩阵,然后用这个降维矩阵对测试样本和训练样本降维,我们的测试样本是4096*1的矩阵,降维的时候这样:
    Y_test=UL'*X_test;

    UL是计算获得降维矩阵,UL' (对UL进行转至)获得的19*4096的矩阵,19*4096 * 4096*1,就获得了19*1的降维后的数据。

    如果是使用matlab自带的princomp进行降维,那么得到的coeff就是降维矩阵,使用测试样本,这里的训练样本和测试样本都要转换成行向量,每一行表示一个样本,测试样本是1*4096,降维矩阵是 4096*29,那么就是 用待降维的样本 x乘上降维矩阵 , x * coeff ,注意这两种不同的样本表示方法中降维的使用,降维矩阵的不同位置。这样降维后获得1*4096 * 4096*29 = 1*29 的降维后的数据。

    通过 上面的自己实现的pca降维的代码,还可以对降维后的数据进行重建,获得重建后的图像,上面的程序中已经给出了。下面给出一个通过princomp降维后再对降维后的数据进行重建的程序。

    通过 princomp降维后的数据进行重建


    [csharp] view plaincopy
    1. clear;
    2. clc;
    3. train_path='E:\TrainingSet\angry\positive\';
    4. images = dir('E:\TrainingSet\angry\positive\*.bmp');
    5. phi=zeros(30,64*64);
    6. % 加载样本图像到 30*(64*64)的矩阵中,每一行代表一幅图像
    7. for i=1:30
    8. path=strcat(train_path,images(i).name);
    9. Image=imread(path);
    10. Image=imresize(Image,[64,64]);
    11. phi(i,:)=double(reshape(Image,1,[]));
    12. end;
    13. % 计算平均脸,并保存用以查看
    14. mean_phi=mean(phi,1);
    15. mean_face=reshape(mean_phi,64,64);
    16. Image_mean=mat2gray(mean_face);
    17. imwrite(Image_mean,'meanface2.bmp','bmp');
    18. % 使用matlab自带的pca进行降维
    19. [coeff, score, latent, TSQUARED] = princomp(phi,'econ');
    20. %display Eigenface
    21. for i=1:29
    22. Eigenface=reshape(coeff(:,i),[64,64]);
    23. figure(i);
    24. imshow(mat2gray(Eigenface));
    25. end
    26. % 进行测试
    27. %使用测试样本进行测试
    28. clc;
    29. test_path='E:\BIT\code\FER\meanface.bmp';
    30. error=zeros([1,4]);
    31. Image=imread(test_path);
    32. Image=double(imresize(Image,[64,64]));
    33. phi_test=zeros(1,64*64);
    34. phi_test(1,:)=double(reshape(Image,1,[])); % 读入的测试图像保存为一行,行向量
    35. X_test=phi_test-mean_phi; % 检测训练样本的平均脸
    36. Y_test=X_test*coeff; % 进行降维<SPAN style="BACKGROUND-COLOR: rgb(248,248,248)"></SPAN>
    [csharp] view plain copy
    1. clear;  
    2. clc;  
    3. train_path='E:\TrainingSet\angry\positive\';  
    4. images = dir('E:\TrainingSet\angry\positive\*.bmp');   
    5. phi=zeros(30,64*64);  
    6.   
    7. % 加载样本图像到 30*(64*64)的矩阵中,每一行代表一幅图像  
    8. for i=1:30  
    9.     path=strcat(train_path,images(i).name);  
    10.     Image=imread(path);  
    11.     Image=imresize(Image,[64,64]);  
    12.     phi(i,:)=double(reshape(Image,1,[]));  
    13. end;  
    14.   
    15. % 计算平均脸,并保存用以查看  
    16. mean_phi=mean(phi,1);  
    17. mean_face=reshape(mean_phi,64,64);  
    18. Image_mean=mat2gray(mean_face);  
    19. imwrite(Image_mean,'meanface2.bmp','bmp');  
    20.   
    21. % 使用matlab自带的pca进行降维  
    22. [coeff, score, latent, TSQUARED] = princomp(phi,'econ');  
    23.   
    24. %display Eigenface  
    25. for i=1:29  
    26.     Eigenface=reshape(coeff(:,i),[64,64]);  
    27.     figure(i);  
    28.     imshow(mat2gray(Eigenface));  
    29. end  
    30.   
    31. % 进行测试  
    32. %使用测试样本进行测试  
    33. clc;  
    34. test_path='E:\BIT\code\FER\meanface.bmp';  
    35. error=zeros([1,4]);  
    36.   
    37. Image=imread(test_path);  
    38. Image=double(imresize(Image,[64,64]));  
    39. phi_test=zeros(1,64*64);  
    40. phi_test(1,:)=double(reshape(Image,1,[])); % 读入的测试图像保存为一行,行向量  
    41. X_test=phi_test-mean_phi; % 检测训练样本的平均脸  
    42. Y_test=X_test*coeff;  % 进行降维<span style="background-color:rgb(248,248,248)"></span>  
    [csharp] view plaincopy
    1. X_test_re=Y_test*coeff'; % 重构
    2. Face_re=X_test_re+mean_phi;
    3. %calculate error rate
    4. e=Face_re-phi_test;
    5. %%display figure
    6. Face_re_2=reshape(Face_re(1,:),[64,64]);
    7. figure(i);
    8. imshow(mat2gray(Image));
    9. title('Original');
    10. figure(10+i);
    11. imshow(mat2gray(Face_re_2));
    12. title('Reconstruct');
    13. error(1,i)=norm(e);
    14. %dispaly error rate
    15. error_rate=error(1,i);
    16. display(error_rate);
    [csharp] view plain copy
    1. X_test_re=Y_test*coeff'; % 重构  
    2. Face_re=X_test_re+mean_phi;  
    3. %calculate error rate  
    4. e=Face_re-phi_test;  
    5.   
    6. %%display figure  
    7. Face_re_2=reshape(Face_re(1,:),[64,64]);  
    8. figure(i);  
    9.   
    10. imshow(mat2gray(Image));  
    11. title('Original');  
    12. figure(10+i);  
    13. imshow(mat2gray(Face_re_2));  
    14. title('Reconstruct');  
    15. error(1,i)=norm(e);  
    16.   
    17. %dispaly error rate  
    18. error_rate=error(1,i);  
    19. display(error_rate);  

    上面的程序关键处都有注释,应该挺好理解的。


    关于网络上的一些解释个人理解(仅供大家参考理解)


    1.


    原文地址:http://www.cnblogs.com/sunwufan/archive/2011/08/31/2159952.html

    原文:

    最近看了些主成分分析,混迹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))

    例子:

    View Code
    %%
    %清屏
    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,就是在降维与准确性间找一个平衡点的问题,让数据即不会维数多而使运算复杂,又有较高的分辨率。


    我的个人见解:这篇文章中的解释挺靠谱的,可以用来参考。第二点其实matlab的输出结果score这个数据已经是降维后的数据,不过大家可以根据自己的需要取前多少列的数据。


    2。


    原文地址:http://www.ilovematlab.cn/thread-54600-1-1.html

    部分原文:
    回复 8# 5342245 的帖子 设原始数据为X,先不做任何预处理。
    [coef,score,latent,t2] = princomp(X);
    则那些参数的底层算法大体过程如下:
    x0 = bsxfun(@minus,X,mean(X,1)); %x0为将X去均值后的数据。
    [coef,ignore] = eig(x0'*x0); 这就是coef的由来。 【当然最终的还有排序什么乱七八糟的。。】
    scroe = x0*coef % 这就是score的由来,就是一个简单的线性变换,将原来的X的坐标转换到主成分空间中的坐标。仅此而已

    则模型为从原始数据出发:
    score = bsxfun(@minus,X,mean(X,1))*coef;

    逆变换:
    X = bsxfun(@plus,score*inv(coef),mean(X,1))


    以上这些你可以自己验证,看是否正确。
    关于你的第三问。对于每一个主成分,就看coef的相应的列就能知道原始的变量那个对该主成分贡献大了啊。。

    上面是没有预处理的。如果加了可逆的预处理。则原始数据亦可从预处理后的数据表示出。进而 bla bla....
    ===============这回够通俗易懂吧。。O(∩_∩)O
    PS:pca算法流程,你熟悉吗?只要知道那个算法过程。这些都不难理解啊。。
    建议您看看书把pca算法流程再过一遍。。否则别人再怎么说也没用。。。

    我的个人见解:
    这里我想说的是,再对测试样本进行降维的时候,一定要减去训练样本的均值,使用训练样本得到的转换矩阵,保证训练样本和测试样本转换到相同的样本空间中,这样才有意思。大家有时间可以去看看英文的资料,说的都比较详细。再用测试样本减去均值以后,就可以进行转换了。


    减去样本均值:使用bsxfun函数,不然维度会报错
    除以lambda:先将lambda转换成对角矩阵,然后再相除

    很多同学可能在开始的时候和我一样,都是不知道如果对测试样本进行降维,很多人就选择了还是使用princomp这个函数处理测试样本,那么这样测试样本被映射到一个新的空间中,和原来的训练样本完全不是在一个空间,一点意义都没有,还是要使用测试样本减去均值,然后乘上训练样本降维的时候获得降维矩阵,转换到相同的空间中。


    http://blog.csdn.net/gwh111/article/details/11742735

    http://blog.csdn.net/mingtian715/article/details/54172281

    先说我的结论:降维后维数一定要小于数据样本数

    最近在做扭曲图形的识别,思路是用使用一幅静态图像,建立扭曲方程,生成一系列不同形态的扭曲图像,再做Pca降维,生成10个特征基向量,任何一幅扭曲图像都向基向量投影,产生10个特征系数,根据特征系数做识别,其实就是特征脸的过程。


    写这篇文章的主要原因是我在网上搜索Pca,发现有一篇文章很火:PCA降维算法总结以及matlab实现PCA(个人的一点理解),被很多人转载,至于我也搞不清原创到底是谁;但不得不说,经过我的思考,我认为这篇文章中有些内容(即样本数目和降维数目关系)是有问题的,特在此讨论一下,希望得到更多人的意见和看法。


    首先还是从Matlab中的Pca函数说起

    之前自以为对Pca的原理比较清楚,但使用Matlab自带的pca函数时,有些问题困扰了我。下面先介绍一下matlab中pca函数的基本使用:

    简单来说,X是n*p矩阵,每一行对应一个样本,每一列对应一个变量,返回值为特征矩阵。

    下面实验一下,首先假设X=1024*190,即有1024个样本,数据维数为190:

    [plain] view plain copy
    1. eff1 = pca(X);  
    2. size(eff1)  
    3. 190,190;  
    4. Xp = X*eff1(:,1:10);  
    5. size(Xp)  
    6. 1024,10;  

    上面就是把190维数据降到10维的过程,再来看看当X=190*1024时,按理来说此时得到的eff应该是1024*1024,但是:

    [plain] view plain copy
    1. eff2 = pca(X');  
    2. size(eff2)  
    3. 1024,189;  

    特征向量矩阵竟然只有1024*189大小,这意味着,当再做降维(投影时),原数据的第二维尺寸肯定小于等于189,即降维尺寸要小于数据样本数!此外,不光是Matlab自带的pca函数,国外常用的机器学习工具箱pca函数(如下)也是要求降维后尺寸小于等于样本数的,感兴趣的可以尝试一下。

    X还是n*p数据,no_dims代表需要保留维数或者需要保留的数据差异性(0~1);mappedX是降维后数据,mapping为投影矩阵。

    [plain] view plain copy
    1. function [mappedX, mapping] = pca(X, no_dims)  
    2. %PCA Perform the PCA algorithm  
    3. %  
    4. %   [mappedX, mapping] = pca(X, no_dims)  
    5. %  
    6. % The function runs PCA on a set of datapoints X. The variable  
    7. % no_dims sets the number of dimensions of the feature points in the   
    8. % embedded feature space (no_dims >= 1, default = 2).   
    9. % For no_dims, you can also specify a number between 0 and 1, determining   
    10. % the amount of variance you want to retain in the PCA step.  
    11. % The function returns the locations of the embedded trainingdata in   
    12. % mappedX. Furthermore, it returns information on the mapping in mapping.  
    13. %  
    14. %  
    15.   
    16. % This file is part of the Matlab Toolbox for Dimensionality Reduction.  
    17. % The toolbox can be obtained from http://homepage.tudelft.nl/19j49  
    18. % You are free to use, change, or redistribute this code in any way you  
    19. % want for non-commercial purposes. However, it is appreciated if you   
    20. % maintain the name of the original author.  
    21. %  
    22. % (C) Laurens van der Maaten, Delft University of Technology  
    23.   
    24.   
    25.     if ~exist('no_dims', 'var')  
    26.         no_dims = 2;  
    27.     end  
    28.       
    29.     % Make sure data is zero mean  
    30.     mapping.mean = mean(X, 1);  
    31.     X = bsxfun(@minus, X, mapping.mean);  
    32.   
    33.     % Compute covariance matrix  
    34.     if size(X, 2) < size(X, 1)  
    35.         C = cov(X);        
    36.     else  
    37.         C = (1 / size(X, 1)) * (X * X');        % if N>D, we better use this matrix for the eigendecomposition  
    38.     end  
    39.       
    40.     % Perform eigendecomposition of C  
    41.     C(isnan(C)) = 0;  
    42.     C(isinf(C)) = 0;  
    43.     [M, lambda] = eig(C);  
    44.       
    45.     % Sort eigenvectors in descending order  
    46.     [lambda, ind] = sort(diag(lambda), 'descend');  
    47.     if no_dims < 1  
    48.         no_dims = find(cumsum(lambda ./ sum(lambda)) >= no_dims, 1, 'first');  
    49.         disp(['Embedding into ' num2str(no_dims) ' dimensions.']);  
    50.     end  
    51.     if no_dims > size(M, 2)  
    52.         no_dims = size(M, 2);  
    53.         warning(['Target dimensionality reduced to ' num2str(no_dims) '.']);  
    54.     end  
    55.     M = M(:,ind(1:no_dims));  
    56.     lambda = lambda(1:no_dims);  
    57.       
    58.     % Apply mapping on the data  
    59.     if ~(size(X, 2) < size(X, 1))  
    60.         M = bsxfun(@times, X' * M, (1 ./ sqrt(size(X, 1) .* lambda))');     % normalize in order to get eigenvectors of covariance matrix  
    61.     end  
    62.     mappedX = X * M;  
    63.       
    64.     % Store information for out-of-sample extension  
    65.     mapping.M = M;  
    66.     mapping.lambda = lambda;  

    再来说说那篇被广泛转载的博客中:

    在我看来,博主应该是理解错他朋友的话了,这句话的想表达的意思应该是降维后数据维数肯定要小于样本数量,而不是降维之前。

    当然我这里绝不是吹毛求疵,也不是批评这位博主,只是这个问题的确困扰了我,所以在此提出,希望得到更多讨论。


    最后说说为什么降维后数据特征数一定小于样本数?

    简单来说,就是确定一直线至少需要两点,确定一平面至少需要三点,确定n维空间至少需要n点。Pca是将原数据投影到新的空间,因此对于样本数n来说,最多确定n维空间。

    其实举一个例子就很直观:

    上图就是一个将2维数据降维到1维数据的过程,样本数目大于1(降维后维数),可以找到一条直线使得所有点的投影误差和最小,降维过程是有意义的;但如果样本数目不大于1,即只有一个样本,此时降维的过程就意义不大了,因为任取一个过该点的轴都可以使得投影误差最小,即可确定无数子空间。



    http://www.ilovematlab.cn/thread-134496-1-1.html
    训练集和测试集的归一化与PCA主成分分析问题

    整个数据集分为训练集和测试集,我发现对整个训练集+测试集统一归一化(对特征属性的归一化)这样效果要好些,这个目前是没什么疑问,但是这个PCA-主成分分析我是应该先对traindata进行降维得到投影矩阵A,然后用这个投影矩阵A对testdata降维,还是应该对整个训练集+测试集一起做pca降维呢?因为我考虑到pca是一种无监督学习,所以想一起降维,但看到很多论文都是分开进行,那样和LDA是一样的做法,有没有比较权威的做法呢?望高手指教!

    回答:降维只对一个集降维,将投影矩阵作用到另外一个集上,才能保证两个集在同一个空间中。而不是分别降维

    目前自己是先将训练集进行pca降维 得到均值 映射矩阵和lambda,再用测试集减去均值后再与映射矩阵相乘得到投影的测试矩阵。 除以lambda后matlab提示数据可能错误。

    展开全文
  • PCA降维的原理及步骤

    2017-04-10 16:49:42
    *****降维的作用***** ①数据在低维下更容易处理、更容易使用; ②相关特征,特别是重要特征更能在数据中明确的显示出来;如果只有两维或者三维的话,更便于可视化展示; ③去除数据噪声 ④降低算法开销 ...
  • PCA(Principal Component Analysis)主成分分析算法,在进行图像识别以及高维度数据降维处理中有很强的应用性,算法主要通过计算选择特征值较大的特征向量来对原始数据进行线性变换,不仅可以去除无用的噪声,还能...
  • Python数据挖掘笔记 七 .PCA降维操作及subplot子图绘制 这篇文章主要介绍四个知识点,也是我那节课讲课的内容。 1.PCA降维操作; 2.Python中Sklearn的PCA扩展包; 3.Matplotlib的subplot函数绘制子图; 4.通过...
  • 本来最早的时候我没有打算对提取的gabor特征进行降维,但是如果一个图像时64*64,那么使用五个尺度八个方向的gabor滤波器进行滤波,这样提取的特征足足有64*64*5*8这么多,如果图像稍微大一点,比如12
  • 关于opencv 里面的 PCA降维 今天终于把opencv自带的降维函数跑通了,花了我一天时间,, 首先得感谢这篇博客的作者: http://blog.codinglabs.org/articles/pca-tutorial.html 看了他的“PCA的数学原理”,真的有种...
  • sklearn实现PCA降维

    2019-08-22 19:38:51
    pca听起来是不是很不怎么样,但是但凡你是大数据方向的,那么你可就要警惕一下了,没了它你可能会无从下手对于上千,万维度的数据特征处理起来,下来我就先简单解释一下PCA是何方神圣 PCA概要 PCA的思想是将n维...
  • PCA降维(MATLAB实践)

    2017-08-25 17:00:55
    PCA原理PCA的原理就是将原来的样本数据投影到一个新的空间中,相当于我们在矩阵分析里面学习的将一组矩阵映射到另外的坐标系下。通过一个转换坐标,也可以理解成把一组坐标转换到另外一组坐标系下,但是在新的坐标系...
  • PCA降维涉及高维数据的问题容易陷入维数灾难,随着数据集维数的增加,算法学习所需的样本数量呈指数级增加,且需要更多的内存和处理能力,消耗资源。主成分分析也称为K-L变换,常用于高位数据预处理和可视化。PCA...
  • PCA图像降维简单原理

    2019-04-26 19:27:56
    1、关于图片的展示方式疑问?...但是对图片进行处理时,需要将图片转化为精度更高的格式,所以就会进行如下操作: >> I = double(imread('house.jpg')); 这个时候执行 >> figure,...
  • PCA降维及使用

    2019-05-23 18:11:46
    1、降维作用 数据在低维下更容易处理、更容易使用; 相关特征,特别是重要特征更能在数据中明确的显示出来;如果只有两维或者三维的话,更便于可视化展示; 去除数据噪声 降低算法开销 import numpy as np from ...
  • BP神经网络+PCA降维测试MNIST数据集一.BP神经网络1.网络架构2.反向传播二.PCA降维三.代码实现1.制作训练数据2.PCA降维3.BP神经网络训练4.测试及结果存储 经过多天的努力,成功完成了自己的第一次实战,特此记录。 一...
  • PCA降维原理和作用

    2018-10-31 20:19:04
    降维的作用 ①数据在低维下更容易处理、更容易使用; ②相关特征,特别是重要特征更能在数据中明确的显示出来;如果只有两维或者三维的话,更便于可视化展示; ③去除数据噪声 ④降低算法开销 降维通俗点的解释 一些...
  • 关于 PCA 算法的讲解文章... 解释方差,它是 PCA 降维维度的重要指标,一般选取累计贡献率在90%左右的维度作为PCA 降维的参考维度。在识别算法的实现过程中,当我们求得某一数据库各类别特征参考维度时,取最大维度
  • PCA降维+SVM 算法进行人脸识别 SVM基本原理: 给定训练样本集,在特征空间上找到一个分离超平面将点不同的类 给定训练样本集,在特征空间上找到一个分离超平面将点不同的类 给定训练样本集,在特征空间上找到一个...
  • PCA降维原理以及举例

    2018-03-28 18:42:14
    图像读取之后,如若将每一个像素点看做特征,数据过于庞大和冗余,同时为了速度和可视化效果应先对读取进来的数据进行降维处理。1.1消减维度的理由:(1)大多数的模型在维度较小的情况下比较安全,多余的特征会影响...
1 2 3 4 5 ... 20
收藏数 9,122
精华内容 3,648
关键字:

pca降维 图像处理