Search code examples
pythonpca

How to reconstruct image from first component in Python after PCA?


How to reconstruct image from first component in Python after PCA?

My attempt:

from sklearn.datasets import load_sample_image
from sklearn.feature_extraction import image
from sklearn.decomposition import PCA
# Create patches of size 25 by 25 and create a matrix from all patches
patches = image.extract_patches_2d(grayscale_image, (25, 25), random_state = 42)
#reshape patches
patches_reshaped = patches.reshape(patches.shape[0],-1)
# PCA
pca = PCA(n_components = 3,random_state = 42)
pca.fit(patches_reshaped)
first_component = pca.components_[0] #first component
# attempt to reconstruct image from first component
plt.imshow(pca.components_[0].reshape(25, 25),"gray")

Solution

  • You have passed n_components = 3 to PCA, meaning you will have three principal components. So when you do,

    projected = pca.fit_transform(patches_reshaped.data)
    

    You will get your data projected in three 3 principal axes, meaning your output will be of shape (patches.shape[0], 3).

    Now to reconstruct using the first principal component, what you have to do is get the projection of your data on this princpical axis and do an inverse transform to your original domain. To do this, first get the first principal component:

    # First get your first component
    first_component = pca.components_[0]
    # Make sure your first component is a row vector
    first_component = first_component.reshape(1,-1) 
    

    Then, The inverse transform is nothing but projected_data * principal_components. For more details you can look into the documentation here and the source code here.

    # get the first projection 
    first_proj = projected[:,0]
    # Make sure your first component is a column vector
    first_proj = first_proj.reshape(-1,1)
    # do inverse transform (No you have to add the mean as thse algorithm 
    # works on zero mean data) 
    recon_using_first_comp = np.dot(proj, first_component) + pca.mean_
    

    Then reconstruct the patches to get your final image

    final_img = image.reconstruct_from_patches_2d(recon_using_first_comp.reshape(-1,25,25), grayscale_image.shape)