主分量分析(PCA)

       把從混合信號中求出主分量(能量最大的成份)的方法稱爲主分量分析(PCA),而次分量(Minor Components,MCs)與主分量(Principal Components,PCs)相對,它是混合信號中能量最小的成分,被認爲是不重要的或是噪聲有關的信號,把確定次分量的方法稱爲次分量分析(MCA).

       PCA可以用於減少特徵空間維數、確定變量的線性組合、選擇最有用的變量、變量辨識、識別目標或是異常值分組等。主分量子空間提供了從高維數據到低維數據在均方誤差意義下的數據壓縮,它能最大程度地減少方差。

     由於PCA實際計算中只涉及到輸入數據概率密度分佈函數(Pdf)的二階特性(協方差矩陣),所以解出的各主分量只互相正交(不相關),但並不滿足相互獨立。而且信號的大部分重要特徵往往包含在Pdf的高階統計特性中,所以只有多變量觀測數據是由高斯分佈的源信號構成,PCA方法纔有效。

     非線性PCA(NLPCA)即將高階累積量引入標準的PCA中,是由芬蘭學者Karhunen和Oja首先提出並將其應用於ICA。它的可以完成對輸入信號的盲分離。高階累積量是以隱含的方式引入計算的,採用自適應迭代方法便於工程實現。標準的PCA基於信號的協方差矩陣僅能處理高斯信號,而NLPCA可以處理非高斯信號。

PCA(Principal Component Analysis),即主成分分析,主要用於數據降維。
     對於一組樣本的feature組成的多維向量,多維向量裏的某些元素本身沒有區分性,比如某個元素在所有的樣本中都爲1,或者與1差距不大,那麼這個元素本身就沒有區分性,用它做特徵來區分,貢獻會非常小。所以我們的目的是找那些變化大的元素,即方差大的那些維,而去除掉那些變化不大的維,從而使feature留下的都是最能代表此元素的“精品”,而且計算量也變小了。

      對於一個k維的feature來說,相當於它的每一維feature與其他維都是正交的(相當於在多維座標系中,座標軸都是垂直的),那麼我們可以變化這些維的座標系,從而使這個feature在某些維上方差大,而在某些維上方差很小。例如,一個45度傾斜的橢圓,在第一座標系,如果按照x,y座標來投影,這些點的x和y的屬性很難用於區分他們,因爲他們在x,y軸上座標變化的方差都差不多,我們無法根據這個點的某個x屬性來判斷這個點是哪個,而如果將座標軸旋轉,以橢圓長軸爲x軸,則橢圓在長軸上的分佈比較長,方差大,而在短軸上的分佈短,方差小,所以可以考慮只保留這些點的長軸屬性,來區分橢圓上的點,這樣,區分性比x,y軸的方法要好!

      所以我們的做法就是求得一個k維特徵的投影矩陣,這個投影矩陣可以將feature從高維降到低維。投影矩陣也可以叫做變換矩陣。新的低維特徵必須每個維都正交,特徵向量都是正交的。通過求樣本矩陣的協方差矩陣,然後求出協方差矩陣的特徵向量,這些特徵向量就可以構成這個投影矩陣了。特徵向量的選擇取決於協方差矩陣的特徵值的大小。

      舉一個例子:

      對於一個訓練集,100個樣本,feature是10維,那麼它可以建立一個100*10的矩陣,作爲樣本。求這個樣本的協方差矩陣,得到一個10*10的協方差矩陣,然後求出這個協方差矩陣的特徵值和特徵向量,應該有10個特徵值和特徵向量,我們根據特徵值的大小,取前四個特徵值所對應的特徵向量,構成一個10*4的矩陣,這個矩陣就是我們要求的特徵矩陣,100*10的樣本矩陣乘以這個10*4的特徵矩陣,就得到了一個100*4的新的降維之後的樣本矩陣,每個樣本的維數下降了。

      當給定一個測試的feature集之後,比如1*10維的feature,乘以上面得到的10*4的特徵矩陣,便可以得到一個1*4的feature,用這個feature去分類。

      所以做PCA實際上是求得這個投影矩陣,用高維的特徵乘以這個投影矩陣,便可以將高維特徵的維數下降到指定的維數。

      在opencv裏面有專門的函數,可以得到這個這個投影矩陣(特徵矩陣)。

      void cvCalcPCA( const CvArr* data, CvArr* avg, CvArr* eigenvalues, CvArr* eigenvectors, int flags );

      簡單使用 cvCalcPCA 計算主成分的代碼如下:
             CvMat* pData = cvCreateMat(100, 2, CV_32FC1); //二維數據點
             for(int i = 0; i < 100; i++)
             {
                 cvSet2D(pData, i, 0,cvRealScalar(i));
                 cvSet2D(pData, i, 1,cvRealScalar(i));
             }

             CvMat* pMean = cvCreateMat(1, 2, CV_32FC1);
             CvMat* pEigVals = cvCreateMat(1, 2, CV_32FC1);
             CvMat* pEigVecs = cvCreateMat(2, 2, CV_32FC1);

             cvCalcPCA(pData, pMean, pEigVals, pEigVecs, CV_PCA_DATA_AS_ROW );

             float pp[100];
             memcpy(pp,pEigVals->data.fl,100 );
             memcpy(pp,pEigVecs->data.fl,100 );
             memcpy(pp,pMean->data.fl,100 );

....................................................................................................................................................................................

程序說明:y = pca(mixedsig),程序中mixedsig爲 n*T 階混合數據矩陣,n爲信號個數,T爲採樣點數, y爲 m*T 階主分量矩陣。

程序設計步驟:

1、去均值

2、計算協方差矩陣及其特徵值和特徵向量

3、計算協方差矩陣的特徵值大於閾值的個數

4、降序排列特徵值

5、去掉較小的特徵值

6、去掉較大的特徵值(一般沒有這一步)

7、合併選擇的特徵值

8、選擇相應的特徵值和特徵向量

9、計算白化矩陣

10、提取主分量

程序代碼

%程序說明:y = pca(mixedsig),程序中mixedsig爲 n*T 階混合數據矩陣,n爲信號個數,T爲採樣點數

% y爲 m*T 階主分量矩陣。

function y = pca(mixedsig)

if nargin == 0

      error('You must supply the mixed data as input argument.');

end

if length(size(mixedsig))>2

      error('Input data can not have more than two dimensions. ');

end

if any(any(isnan(mixedsig)))

      error('Input data contains NaN''s.');

end

%——————————————去均值————————————

meanValue = mean(mixedsig')';

mixedsig = mixedsig - meanValue * ones(1,size(meanValue,2));

[Dim,NumofSampl] = size(mixedsig);

oldDimension = Dim;

fprintf('Number of signals: %d\n',Dim);

fprintf('Number of samples: %d\n',NumofSampl);

fprintf('Calculate PCA...');

firstEig = 1;

lastEig = Dim;

covarianceMatrix = cov(mixedsig',1);      %計算協方差矩陣

[E,D] = eig(covarianceMatrix);            %計算協方差矩陣的特徵值和特徵向量

%———計算協方差矩陣的特徵值大於閾值的個數lastEig———

rankTolerance = 1e-5;

maxLastEig = sum(diag(D)) > rankTolerance;

lastEig = maxLastEig;

%——————————降序排列特徵值——————————

eigenvalues = flipud(sort(diag(D)));

%—————————去掉較小的特徵值——————————

if lastEig < oldDimension

      lowerLimitValue = (eigenvalues(lastEig) + eigenvalues(lastEig + 1))/2;

else

      lowerLimitValue = eigenvalues(oldDimension) - 1;

end

lowerColumns = diag(D) > lowerLimitValue;

%—————去掉較大的特徵值(一般沒有這一步)——————

if firstEig > 1

      higherLimitValue = (eigenvalues(firstEig - 1) + eigenvalues(firstEig))/2;

else

      higherLimitValue = eigenvalues(1) + 1;

end

higherColumns = diag(D) < higherLimitValue;

%—————————合併選擇的特徵值——————————

selectedColumns =lowerColumns & higherColumns;

%—————————輸出處理的結果信息—————————

fprintf('Selected[ %d ] dimensions.\n',sum(selectedColumns));

fprintf('Smallest remaining (non-zero) eigenvalue[ %g ]\n',eigenvalues(lastEig));

fprintf('Largest remaining (non-zero) eigenvalue[ %g ]\n',eigenvalues(firstEig));

fprintf('Sum of removed eigenvalue[ %g ]\n',sum(diag(D) .* (~selectedColumns)));

%———————選擇相應的特徵值和特徵向量———————

E = selcol(E,selectedColumns);

D = selcol(selcol(D,selectedColumns)',selectedColumns);

%——————————計算白化矩陣———————————

whiteningMatrix = inv(sqrt(D)) * E';

dewhiteningMatrix = E * sqrt(D);

%——————————提取主分量————————————

y = whiteningMatrix * mixedsig;

%——————————行選擇子程序———————————

function newMatrix = selcol(oldMatrix,maskVector)

if size(maskVector,1)~ = size(oldMatrix,2)

      error('The mask vector and matrix are of uncompatible size.');

end

numTaken = 0;

for i = 1:size(maskVector,1)

      if maskVector(i,1) == 1

          takingMask(1,numTaken + 1) == i;

          numTaken = numTaken + 1;

      end

end

newMatrix = oldMatrix(:,takingMask);

對圖像表示和描述的思考:運用主分量進行描繪,使用主特徵向量排列二維對象的概念在圖像描述中起着重要的作用。圖像的描述對於大小的變化、平移、旋轉變化本應是儘可能獨立的。使用對象的主軸校正能力爲消除旋轉變化的影響提供一種可靠的手段。特徵值是沿着本徵軸的方差,並可用於尺寸的歸一化。平移帶來的影響可以通過將對象的均值設定爲中心來解決。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章