How to retro-engineer hyperPCA and obtain the components from the coefficients and original input?
2 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Federico
le 10 Fév 2022
Modifié(e) : Mahesh Belagal Sarvisetty
le 17 Fév 2022
Dear all, I am using the hyperpca matlab function to obtain the principal components for some hyperspectral images. The function is called like this:
[components,coefficients,variance]=hyperpca(hypercube,numcoefficients);
Where hypercube is the hyperspectral image passed as an m*n*p int16 matrix.
If I understand correctly PCA is a function reprojecting the input data (hypercube) into the components space (components) and therefore a linear function.
My expectations would be that multiplying the input data by the coefficients would return the principal components. I proceeded as follows:
reshaped_inputs=reshape(hypercube,size(hypercube,1)*size(hypercube,2),size(hypercube,3));
reshaped_new_components=single(reshaped_inputs)*coefficients; % need to cast the inputs from int16 to single otherwise mtimes won't work
new_components=reshape(reshaped_new_components,size(hypercube,1),size(hypercube,2),size(coefficients,2));
I would then expect that new_components is == components, but instead the difference between those two matrices is far from zero.
Why is that? Is there some sort of scaling/centering that I'm missing?
Thanks for any inputs!
0 commentaires
Réponse acceptée
Mahesh Belagal Sarvisetty
le 16 Fév 2022
By default, hyperpca mean-centering the input data in order to compute principal components. So, you can set MeanCentered value as false to match new_components with the components from the hyperpca function or you can mean center the input data before multiplying with the coefficients.
Here is quick snippet with MeanCentered value false
% Read Hypercube
hCube = hypercube("paviaU.dat");
% Perform PCA
[princComp, coeff] = hyperpca(hCube,20,"MeanCentered",false);
% Extract and reshape the DataCube
dataCube = (hCube.DataCube);
sz = size(dataCube);
dataCube = reshape(dataCube,[sz(1)*sz(2) sz(3)]);
% Generate the new principal component
newPrincComp = dataCube * coeff;
sz = size(princComp);
newPrincComp = reshape(newPrincComp,[sz(1) sz(2) sz(3)]);
% Calculate max absolute difference
diff = imabsdiff(princComp,newPrincComp);
max(diff(:))
2 commentaires
Mahesh Belagal Sarvisetty
le 17 Fév 2022
Modifié(e) : Mahesh Belagal Sarvisetty
le 17 Fév 2022
inverseProjection input 'coeff' contains coefficients for only 10 principal components. In order to reconstruct original data we have use coefficients of all principal components and also set the MeanCentered value as false.
Take a look at this example, reconstructedData is same as original datacube
hcube = hypercube('indian_pines.dat');
[pcDataCube,coeff] = hyperpca(hcube,220,"MeanCentered",false);
reconstructedData = inverseProjection(pcDataCube,coeff);
% Difference calculation
diff = imabsdiff(hcube.DataCube,reconstructedData);
disp(['Minimum difference: ',sprintf('%.2f',min(diff(:)))]);
disp(['Average difference: ',sprintf('%.2f',mean(diff(:)))]);
disp(['Maximum difference: ',sprintf('%.2f',max(diff(:)))]);
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Hyperspectral Image Processing dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!