1. 程式人生 > >PCA降維演算法總結以及matlab實現PCA(個人的一點理解)

PCA降維演算法總結以及matlab實現PCA(個人的一點理解)

轉載請宣告出處。by watkins song

兩篇文章各有側重, 對照看效果更加 o(∩∩)o..

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個最大主元對應的“特徵臉”

測試
測試用樣本:

  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降維後的資料進行重建

clear;
clc;
train_path='E:\TrainingSet\angry\positive\';
images = dir('E:\TrainingSet\angry\positive\*.bmp'); 
phi=zeros(30,64*64);

% 載入樣本影象到 30*(64*64)的矩陣中,每一行代表一幅影象
for i=1:30
    path=strcat(train_path,images(i).name);
    Image=imread(path);
    Image=imresize(Image,[64,64]);
    phi(i,:)=double(reshape(Image,1,[]));
end;

% 計算平均臉,並儲存用以檢視
mean_phi=mean(phi,1);
mean_face=reshape(mean_phi,64,64);
Image_mean=mat2gray(mean_face);
imwrite(Image_mean,'meanface2.bmp','bmp');

% 使用matlab自帶的pca進行降維
[coeff, score, latent, TSQUARED] = princomp(phi,'econ');

%display Eigenface
for i=1:29
    Eigenface=reshape(coeff(:,i),[64,64]);
    figure(i);
    imshow(mat2gray(Eigenface));
end

% 進行測試
%使用測試樣本進行測試
clc;
test_path='E:\BIT\code\FER\meanface.bmp';
error=zeros([1,4]);

Image=imread(test_path);
Image=double(imresize(Image,[64,64]));
phi_test=zeros(1,64*64);
phi_test(1,:)=double(reshape(Image,1,[])); % 讀入的測試影象儲存為一行,行向量
X_test=phi_test-mean_phi; % 檢測訓練樣本的平均臉
Y_test=X_test*coeff;  % 進行降維<span style="background-color: rgb(248, 248, 248);"></span>
X_test_re=Y_test*coeff'; % 重構
Face_re=X_test_re+mean_phi;
%calculate error rate
e=Face_re-phi_test;

%%display figure
Face_re_2=reshape(Face_re(1,:),[64,64]);
figure(i);

imshow(mat2gray(Image));
title('Original');
figure(10+i);
imshow(mat2gray(Face_re_2));
title('Reconstruct');
error(1,i)=norm(e);

%dispaly error rate
error_rate=error(1,i);
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,
            
           

相關推薦

PCA演算法總結以及matlab實現PCA(個人一點理解)

轉載請宣告出處。by watkins song 兩篇文章各有側重, 對照看效果更加 o(∩∩)o.. PCA的一些基本資料 最近因為最人臉表情識別,提取的gabor特徵太多了,所以需要用PCA進行對提取的特徵進行降維。 本來最早的時候我沒有打算對提取的gabor特徵

PCA 演算法詳解 以及程式碼示例

%% Initialization clear ; close all; clc fprintf('this code will load 12 images and do PCA for each face.\n'); fprintf('10 images are used to train PCA an

機器學習筆記(八):PCA演算法

1 - PCA概述 主成份分析,簡稱為PCA,是一種非監督學習演算法,經常被用來進行 資料降維 有損資料壓縮 特徵抽取 資料視覺化 2 - PCA原理詳解 通過計算資料矩陣的協方差矩陣,然後得到協方差矩陣的特徵值特徵向量,選擇特

一步步教你輕鬆學主成分分析PCA演算法

(白寧超 2018年10月22日10:14:18) 摘要:主成分分析(英語:Principal components analysis,PCA)是一種分析、簡化資料集的技術。主成分分析經常用於減少資料集的維數,同時保持資料集中的對方差貢獻最大的特徵。常常應用在文字處理、人臉識別、圖片識別、自然語言處

機器學習中優化演算法總結以及Python實現

機器學習演算法最終總是能轉化為最優化問題,習慣上會轉化為最小化問題。 個人總結迭代優化演算法關鍵就兩點: (1) 找到下降方向 (2) 確定下降步長 最速梯度下降演算法 梯度下降演算法是以最優化函式的梯度為下降方向,學習率η\etaη乘以梯度的模即為下降步長。更

matlab實現PCA

利用PCA,把二維資料降為一維資料 load ('ex7data1.mat'); %變成一維 K = 1; %對資料歸一化 means = mean(X); X_means = bsxfun(@min

MATLAB自帶工具箱實現PCA程式碼,著重介紹實現方法

最近專案中需要進行PCA降維,環境是MATLAB,但是在網上找了很多都是介紹PCA原理的,的確介紹的很仔細,但是我是一個工科狗,只是想最快查到用程式碼實現降維的方法而已,網上的對我來說太多了,因此在此做一個總結,出於對知識的 尊重,插兩篇介紹的不錯的PCA 原理文章,只是想實

PCA的原理、方法、以及python實現

參考:菜菜的sklearn教學之降維演算法.pdf!! PCA(主成分分析法) 1. PCA(最大化方差定義或者最小化投影誤差定義)是一種無監督演算法,也就是我們不需要標籤也能對資料做降維,這就使得其應用範圍更加廣泛了。那麼PCA的核心思想是什麼呢? 例如D維變數構成的資料集,PCA的目標是將資料投影到維度

吳恩達機器學習 - PCA演算法 吳恩達機器學習 - PCA演算法

原 吳恩達機器學習 - PCA演算法降維 2018年06月25日 13:08:17 離殤灬孤狼 閱讀數:152 更多

淺談PCA(主成分分析)線性演算法用法

sklearn.decomposition.PCA(n_components = None, copy = True, whiten = False) n_components表示需要保留的主成分個數,即需要降低到幾維;若n_components=1,則表

樸素貝葉斯演算法實現分類以及Matlab實現

開始 其實在學習機器學習的一些演算法,最近也一直在看這方面的東西,並且嘗試著使用Matlab進行一些演算法的實現。這幾天一直在看得就是貝葉斯演算法實現一個分類問題。大概經過了一下這個過程: 看書→演算法公式推演→網上查詢資料→進一步理解→蒐集資料集開始嘗

PCA以及Kmeans聚類例項----python,sklearn,PCA,Kmeans

PCA 演算法也叫主成分分析(principal components analysis),主要是用於資料降維的。關於降維,可以這樣理解,一組資料有n個feature(客戶年齡,收入,每個月消費額度等

2018-4-8蟻群演算法---包子陽《智慧優化演算法以及Matlab實現》第五章

資料來源:《智慧優化演算法以及matlab實現》包子陽  餘繼周 編著第五章-----蟻群演算法是一種元啟發式優化演算法(自己理解:就是作為群體的單位個體也就是元,在裡面充當著隨機的選擇搜尋的方向,有助於全域性勘探)啟發:自然界的螞蟻有能力在沒有然和提示的情況下找到從巢穴矩離

迴歸學習演算法---偏最小二乘迴歸、PCA與理論

1、相關係數的意義與原理   在研究中我們經常要研究多個變數之間的相關性,這些變數可以是自變數與自變數之間、或者是自變數與因變數之間的相關性,為了表示這種相關性,我們引入了相關係數這個概念。這裡使用的

PCA原理以及舉例

將影象讀取之後,如若將每一個畫素點看做特徵,資料過於龐大和冗餘,同時為了速度和視覺化效果應先對讀取進來的資料進行降維處理。1.1消減維度的理由:(1)大多數的模型在維度較小的情況下比較安全,多餘的特徵會影響或誤導學習器;(2)更多的特徵需要調整更多的引數,容易產生過擬合;(3

演算法PCA

降維方法 1、主成分分析(PCA) 在PCA中,資料從原來的座標系轉換到新的座標系,新座標系的選擇是由資料本身決定的。第一個新座標軸選擇的是原始資料中方差最大的方向,第二個新座標軸選擇和第一個座標軸正交且具有最大方差的方向。該過程一直重複,重複次數為原始資料

四大機器學習演算法PCA、LDA、LLE、Laplacian Eigenmaps

引言 機器學習領域中所謂的降維就是指採用某種對映方法,將原高維空間中的資料點對映到低維度的空間中。降維的本質是學習一個對映函式 f : x->y,其中x是原始資料點的表達,目前最多使用向量表達形式。 y是資料點對映後的低維向量表達,通常y的維度小於x的維度(當然提

PCA方法的python實現

參考《機器學習實戰》,使用MNIST資料集 首先給出PCA的演算法 輸入:樣本集             低維空間維數 d‘ 過程: 對所有樣本進行中心化: 計算樣本的協方差矩陣 對協方差矩陣做特徵值分解 取最大的d'個特徵值所對應的特徵向量 輸出:投影矩陣

matlab 程式碼 一些常用的 演算法

http://sugiyama-www.cs.titech.ac.jp/~sugi/software/ Software The software available below is free of charge for research and educatio

metropolis演算法的簡單c++實現以及matlab實現

metropolis是一種取樣方法,一般用於獲取某些擁有某些比較複雜的概率分佈的樣本。 1.取樣最基本的是隨機數的生成,一般是生成具有均勻分佈的隨機數,比如C++裡面的rand函式,可以直接採用。 2.取樣複雜一點是轉化發,用於生成普通常見的分佈,如高斯分佈,它的一般是通過