PCA降維方法
PCA (主成分分析)詳解 (寫給初學者) 結合matlab
一、簡介
PCA(Principal Components Analysis)即主成分分析,是影象處理中經常用到的降維方法,大家知道,我們在處理有關數字影象處理方面的問題時,比如經常用的影象的查詢問題,在一個幾萬或者幾百萬甚至更大的資料庫中查詢一幅相近的影象。這時,我們通常的方法是對影象庫中的圖片提取響應的特徵,如顏色,紋理,sift,surf,vlad等等特徵,然後將其儲存,建立響應的資料索引,然後對要查詢的影象提取相應的特徵,與資料庫中的影象特徵對比,找出與之最近的圖片。這裡,如果我們為了提高查詢的準確率,通常會提取一些較為複雜的特徵,如sift,surf等,一幅影象有很多個這種特徵點,每個特徵點又有一個相應的描述該特徵點的128維的向量,設想如果一幅影象有300個這種特徵點,那麼該幅影象就有300*vector(128維)個,如果我們資料庫中有一百萬張圖片,這個儲存量是相當大的,建立索引也很耗時,如果我們對每個向量進行PCA處理,將其降維為64維,是不是很節約儲存空間啊?對於學習影象處理的人來說,都知道PCA是降維的,但是,很多人不知道具體的原理,為此,我寫這篇文章,來詳細闡述一下PCA及其具體計算過程:
二、PCA詳解
1、原始資料:
為了方便,我們假定資料是二維的,藉助網路上的一組資料,如下:
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
2、計算協方差矩陣
什麼是協方差矩陣?相信看這篇文章的人都學過數理統計,一些基本的常識都知道,但是,也許你很長時間不看了,都忘差不多了,為了方便大家更好的理解,這裡先簡單的回顧一下數理統計的相關知識,當然如果你知道協方差矩陣的求法你可以跳過這裡。
(1)協方差矩陣:
首先我們給你一個含有n個樣本的集合,依次給出數理統計中的一些相關概念:
均值:
標準差:
方差:
既然我們都有這麼多描述資料之間關係的統計量,為什麼我們還要用協方差呢?我們應該注意到,標準差和方差一般是用來描述一維資料的,但現實生活我們常常遇到含有多維資料的資料集,最簡單的大家上學時免不了要統計多個學科的考試成績。面對這樣的資料集,我們當然可以按照每一維獨立的計算其方差,但是通常我們還想了解這幾科成績之間的關係,這時,我們就要用協方差,協方差就是一種用來度量兩個隨機變數關係的統計量,其定義為:
從協方差的定義上我們也可以看出一些顯而易見的性質,如:
(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的列數)
上面我們簡單說了一下協方差矩陣及其求法,言歸正傳,我們用上面簡化求法,求出樣本的協方差矩陣為:
3、計算協方差矩陣的特徵向量和特徵值
因為協方差矩陣為方陣,我們可以計算它的特徵向量和特徵值,如下:
[eigenvectors,eigenvalues] = eig(cov)
我們可以看到這些向量都是單位向量,也就是它們的長度為1,這對PCA來說是很重要的。
4、選擇成分組成模式向量
求出協方差矩陣的特徵值及特徵向量之後,按照特徵值由大到小進行排列,這將給出成分的重要性級別。現在,如果你喜歡,可以忽略那些重要性很小的成分,當然這會丟失一些資訊,但是如果對應的特徵值很小,你不會丟失很多資訊。如果你已經忽略了一些成分,那麼最後的資料集將有更少的維數,精確地說,如果你的原始資料是n維的,你選擇了前p個主要成分,那麼你現在的資料將僅有p維。現在我們要做的是組成一個模式向量,這只是幾個向量組成的矩陣的一個有意思的名字而已,它由你保持的所有特徵向量構成,每一個特徵向量是這個矩陣的一列。
對於我們的資料集,因為有兩個特徵向量,因此我們有兩個選擇。我們可以用兩個特徵向量組成模式向量:
我們也可以忽略其中較小特徵值的一個特徵向量,從而得到如下模式向量:
5、得到降維後的資料
其中rowFeatureVector是由模式向量作為列組成的矩陣的轉置,因此它的行就是原來的模式向量,而且對應最大特徵值的特徵向量在該矩陣的最上一行。rowdataAdjust是每一維資料減去均值後,所組成矩陣的轉置,即資料專案在每一列中,每一行是一維,對我們的樣本來說即是,第一行為x維上資料,第二行為y維上的資料。FinalData是最後得到的資料,資料專案在它的列中,維數沿著行。
這將給我們什麼結果呢?這將僅僅給出我們選擇的資料。我們的原始資料有兩個軸(x和y),所以我們的原始資料按這兩個軸分佈。我們可以按任何兩個我們喜歡的軸表示我們的資料。如果這些軸是正交的,這種表達將是最有效的,這就是特徵向量總是正交的重要性。我們已經將我們的資料從原來的xy軸表達變換為現在的單個特徵矢量表達。
(說明:如果要恢復原始資料,只需逆過程計算即可,即:
)
到此為止,相信你已經掌握了PCA及其原理了。
轉自
http://hi.baidu.com/ifengzh/item/8851b6387aebefc4382ffa60