<jupyter_start><jupyter_text>Principal Component Analysis (PCA) for imagesExamples adapted from https://jakevdp.github.io/PythonDataScienceHandbook/05.09-principal-component-analysis.html<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['axes.titlesize'] = 14
plt.rcParams['legend.fontsize'] = 12
plt.rcParams['figure.figsize'] = (5, 5)
%config InlineBackend.figure_format = 'retina'<jupyter_output><empty_output><jupyter_text>Learning Objectives1. You will understand how images cana be represented as points in a high dimensional space.2. You will be able to apply PCA to images.  Images of hand drawn digits Each 8x8 grayscale image is a point in a 64-dimensional space representing the instensity of each of the 64 pixels in the image.<jupyter_code>from sklearn.datasets import load_digits
digits = load_digits()
images = digits.data
numbers = digits.target

images.shape, numbers.shape<jupyter_output><empty_output><jupyter_text>Each row of `images` is a 64-dimensional data point representing an image of a hand drawn digit.`numbers` are the numerical values 0-9 that each of the 1797 images correspond to.  Visualizing an image of a digit<jupyter_code>i = 0
plt.imshow(images[i,:].reshape(8, 8))
plt.title(f'{numbers[i]}');<jupyter_output><empty_output><jupyter_text>Visualize a bunch of images<jupyter_code>def plot_digits(images, rows=5, cols=10):
    fig, ax = plt.subplots(rows, cols, figsize=(2*cols, 2*rows))
    k = 0
    for i in range(rows):
        for j in range(cols):
            ax[i,j].imshow(images[k,:].reshape(8, 8))
            ax[i,j].set_xticks([])
            ax[i,j].set_yticks([])
            k += 1
plot_digits(images)

for i in range(5):
    print(numbers[i*10:i*10+10])<jupyter_output>[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[0 1 2 3 4 5 6 7 8 9]
[0 9 5 5 6 5 0 9 8 9]
[8 4 1 7 7 3 5 1 0 0]<jupyter_text>Project 64-dimensional images onto a 2-dimensional space for visualization.<jupyter_code>from sklearn.decomposition import PCA

pca = PCA(2)  # project from 64 to 2 dimensions
pcmix = pca.fit_transform(images)

print(images.shape)
print(pcmix.shape)<jupyter_output>(1797, 64)
(1797, 2)<jupyter_text>The two principal components are mixtures of the original 64 dimensions (i.e. mixtures of the original pixel intensities), and thus can themselves be represented as images.<jupyter_code>plt.figure(figsize=(10,5))
plt.subplot(121)
plt.imshow(pca.components_[0].reshape(8, 8))
plt.title('PC0');
plt.subplot(122)
plt.imshow(pca.components_[1].reshape(8, 8))
plt.title('PC1');
plt.tight_layout();<jupyter_output><empty_output><jupyter_text>How do the images cluster according to their digit value in this vastly reduced 2-dimensional space?<jupyter_code>plt.scatter(pcmix[:,0], pcmix[:,1],
            c=numbers, edgecolor='none', alpha=0.5,
            cmap=plt.cm.get_cmap('nipy_spectral', 10))
plt.xlabel('PC0')
plt.ylabel('PC1')
plt.colorbar();<jupyter_output><empty_output><jupyter_text>What do the images look like after projecting onto only two PCs?<jupyter_code>projected_images = pca.inverse_transform(pcmix)

plot_digits(projected_images)<jupyter_output><empty_output><jupyter_text>How well did we do at explaining the variance in the image data with only two PCs?<jupyter_code>pca = PCA()
pca.fit_transform(images)

plt.plot(np.arange(1, 65), np.cumsum(pca.explained_variance_ratio_), 'o-')
plt.xlabel('# PCs')
plt.ylabel('Explained Variance');<jupyter_output><empty_output><jupyter_text>ExerciseUse PCA to project the images dataset onto 20 dimensions.<jupyter_code>...

projected_images = ...

plot_digits(projected_images)<jupyter_output><empty_output><jupyter_text>PCA as a filter for noisy data  Learning Objectives1. You will see how PCA can be used as a filter to remove noise.  Adding some random noise to the images<jupyter_code>np.random.seed(42)
noisy_images = np.random.normal(images, 4)
plot_digits(noisy_images)
# PCA that preserves 50% of the variance in the data
pca = PCA(0.50)
pca.fit(noisy_images)

pca.n_components_
pcmix = pca.transform(noisy_images)
filtered_images = pca.inverse_transform(pcmix)
plot_digits(filtered_images)<jupyter_output><empty_output><jupyter_text>Eigenfaces<jupyter_code># WARNING !!! This is ~200 MB of data which may take a few minutes to download!
# Each face image is 62x47 pixels for a total of 2914 pixels
from sklearn.datasets import fetch_lfw_people
faces = fetch_lfw_people(min_faces_per_person=60)
face_images = faces.data
face_names = faces.target_names

print(face_images.shape)
print(face_names)
plt.figure(figsize=(15, 5))
for i in range(8):
    plt.subplot(1, 8, i+1)
    plt.imshow(face_images[i,:].reshape(62,47), cmap='bone')
    plt.xticks([])
    plt.yticks([])
    plt.title(face_names[i], fontsize=12)<jupyter_output><empty_output><jupyter_text>Project each 2914-dimensional images onto only 150 dimensions.<jupyter_code># PCA for first 150 principal components
# Randomized solver performs some approximates to speed up the computation for high dimensional data sets
pca = PCA(n_components=150, svd_solver='randomized')
pca.fit(face_images)
pca.components_.shape<jupyter_output><empty_output><jupyter_text>First 8 principal components<jupyter_code>plt.figure(figsize=(15, 5))
for i in range(8):
    plt.subplot(1, 8, i+1)
    plt.imshow(pca.components_[i,:].reshape(62,47), cmap='bone')
    plt.xticks([])
    plt.yticks([])
    plt.title(f'PC{i}')<jupyter_output><empty_output><jupyter_text>How much of the variance in the face images does the first 150 PCs explain?<jupyter_code>plt.plot(np.arange(1, 151), np.cumsum(pca.explained_variance_ratio_), 'o-')
plt.xlabel('# PCs')
plt.ylabel('Explained Variance');<jupyter_output><empty_output><jupyter_text>What do the reduced dimension images look like?<jupyter_code>pcmix = pca.transform(face_images)
projected_images = pca.inverse_transform(pcmix)

print(face_images.shape)
print(pcmix.shape)
print(projected_images.shape)
fig, ax = plt.subplots(2, 8, figsize=(15, 5))
for i in range(8):
    # original face
    ax[0,i].imshow(face_images[i,:].reshape(62, 47), cmap='bone')
    ax[0,i].set_xticks([])
    ax[0,i].set_yticks([])
    if i == 0:
        ax[0,i].set_ylabel('Original')
    # projected face
    ax[1,i].imshow(projected_images[i,:].reshape(62, 47), cmap='bone')
    ax[1,i].set_xticks([])
    ax[1,i].set_yticks([])
    if i == 0:
        ax[1,i].set_ylabel('Projected')<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12455516014234876, 'fraction_numerical': 0.0369797307751818, 'mean_word_length': 5.677685950413223, 'pattern_counts': {'":': 0, '<': 63, '<?xml version=': 0, '>': 63, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '333781', 'license': 'Unlicense', 'n_tokens_mistral': 2560, 'n_tokens_neox': 2315, 'n_words': 574, 'path': 'lectures/Apr-29-principal_component_analysis/pca-images.ipynb', 'repo_name': 'nishadalal120/NEU-365P-385L-Spring-2021', 'size': '6463'}