This module examines low-dimensional image representations and cluster stability using boiling images. The legacy Homework 3 PDF/DOCX and tutorials remain available; use the current AI-resilient assignment specification for future offerings, and verify external data/tutorial access before assigning them.
Perform dimensionality reduction and clustering analysis of the same dataset used in HW-2.
(a) Run single value decomposition (SVD) or principal component analysis (PCA) of the images and plot the percentage explained variance vs. the number of principal components (PC).
(b) Pick a representative image, run PCA and plot the reconstructed images using a different number of PCs (e.g. using PC1, PCs 1-2, PCs, 1-10, PCs 1-20, etc.).
(c) Calculate the error of the reconstructed images relative to the original image and plot the error as a function of the number of PCs.
(d) Run a clustering analysis of the boiling images using the PCs (the number of PCs to use is up to your choice) and evaluate the results of clustering.
The dataset for this assignment can be accessed at https://data.mendeley.com/datasets/5kjnphrbsz/1
Unsupervised learning is commonly used for dimensionality reduction and clustering. This is unlike the work we have previously done since it does not use labeled data. Instead is works to find patterns within the data. For this section we will go other some popular unsupervised learning methods that you will implement.
A very common dimensionality reduction algorthim is PCA. It works by defining a new set of basis vectors that capture the most variance. Now that may not make sense yet but please bear with me. As with most things it probably is easist to explain with an example. So let's take a very simple dataset:
| 0 | 0 |
| 2 | 5 |
| 3 | 7 |
| 4 | 6 |
| 5 | 4 |
Okay now pretend this huge dataset is way to large for your computer to handle or maybe you just want to eliminate noise. So you want to reduce the size of it. There are mulitple ways you could reduce the size for example maybe droping one of the
First you need to normalize the data by subtracting by the mean. In this case the mean is
| -2.8 | -4.4 |
| -0.8 | 0.6 |
| 0.2 | 2.6 |
| 1.2 | 1.6 |
| 2.2 | -0.4 |
Next you calculate the covariance matrix. This will describe how each variable varies in relation to the others. Since we have a 2D problem we will have a 2x2 matrix as follows:
Where:
Plugging our values into these equations:
Now with the covariance matrix, you solve for the eigenvectors (
This is something you have probably seen before but I will quickly walk you through it:
Then solving for
You can actually represent every data point as a linear combination of the basis vectors. For example
Now we sort the eigenvalues from highest to lowest.
We define A (the matrix of eigenvectors):
Now we see by putting together our linear combination equations that:
So to solve for our
By doing this we get the new transformed data (the PCs):
| -4.474 | 0.074 |
| 0.09 | 0.51 |
| 2.0 | 0.597 |
| 1.707 | -0.107 |
| 0.674 | -1.074 |
You can transform this data back into the original domain by multipling the transformed data by A.
So now we reduce the dimension by choosing how many PCs we want to retain. For our example we will only keep 1 so we will keep
| -4.474 |
| 0.09 |
| 2.0 |
| 1.707 |
| 0.674 |
This means we can reduce our dataset by half. By doing this we do loose some information. To show this lets try and convert
This figure shows how the data is transformed. You can see how all the transformed points lie on the new basis so they are now in one dimension. You can also see how some information is lost but it still keeps the general trend of the data.
This can be done in scikit-learn:
import numpy as np
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# Define the dataset
data = np.array([[0, 0], [2, 5], [3, 7], [4, 6], [5, 4]])
# Initialize PCA
pca = PCA(n_components=1)
# Fit PCA on the dataset and transform it
transformed_data = pca.fit_transform(data)
# Reconstruct the data using only the first principal component
reconstructed_data = pca.inverse_transform(transformed_data)
# Print the mean, eigenvalues, and eigenvectors
mean = pca.mean_
eigenvalues = pca.explained_variance_
eigenvectors = pca.components_
print("Mean of the dataset:")
print(mean)
print("\nEigenvalues:")
print(eigenvalues)
print("\nEigenvectors:")
print(eigenvectors)
# Plot the original data and the reconstructed data (only 1 principal component)
plt.figure(figsize=(8, 6))
# Plot original data
plt.subplot(1, 2, 1)
plt.scatter(data[:, 0], data[:, 1], color='blue', label='Original Data')
plt.title('Original Data')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True)
# Plot reconstructed data using only 1 principal component
plt.subplot(1, 2, 2)
plt.scatter(reconstructed_data[:, 0], reconstructed_data[:, 1], color='red', label='Reconstructed Data (1 PC)')
plt.title('Reconstructed Data (1 Principal Component)')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid(True)
# Show the plot
plt.tight_layout()
plt.show()
We may want to see how much information is retained by the reduction. This can also be used for determining an apporiate number of pcs to retain. The explained variance formula is based on the eigenvalues:
For this example our explained variance ration for the 1st and second component are:
This is done in python using scikit-learn:
import numpy as np
from sklearn.decomposition import PCA
import matplotlib.pyplot as plt
# Define the dataset
data = np.array([[0, 0], [2, 5], [3, 7], [4, 6], [5, 4]])
# Initialize PCA with 2 components
pca = PCA(n_components=2)
# Fit PCA on the dataset and transform it
pca.fit(data)
# Get the explained variance ratio
explained_variance_ratio = pca.explained_variance_ratio_
# Print the explained variance ratio
print("Explained Variance Ratio:")
print(explained_variance_ratio)
# Plot the explained variance ratio over the components
plt.figure(figsize=(6, 4))
plt.bar(range(1, len(explained_variance_ratio) + 1), explained_variance_ratio, color='blue', alpha=0.7)
plt.title('Explained Variance Ratio by Principal Components')
plt.xlabel('Principal Component')
plt.ylabel('Explained Variance Ratio')
plt.xticks(range(1, len(explained_variance_ratio) + 1))
plt.grid(True)
plt.show()Another type of unsupervised learning is clustering. This is the process of grouping data together based on their similarities. There are several different methods but one common and straight forward method is K-Means clustering. First, let's get a simple dataset. Say we have the following data that describes two animals. We don't know which data belongs to which but we want to split the data into to groups that hopefully correspond with the two different animals.
| id | weight | height |
|---|---|---|
| 1 | 40 | 20 |
| 2 | 2.5 | 10 |
| 3 | 55 | 26 |
| 4 | 3 | 8 |
For this method you first pick how many clusters you want to create. Since we are looking for two animals we will choose 2 clusters. Now we randomly select "centroids" for the clusters. In this case we will choose (2,11) and (6,8).
Now we will calculate the distance from every point to both centroids. We will use the euclidean distance formula:
| id | distance (2,11) | distance (6,8) |
|---|---|---|
| 1 | 39.05 | 36.05 |
| 2 | 1.12 | 4.03 |
| 3 | 55.08 | 52.20 |
| 4 | 3.16 | 3 |
Then, each point is assigned a cluster based on which centroid is the closest. So this this case cluster 1 will consist of point 2 and cluster 2 will consist of points 1,3, and 4. Now, two new centroids are defined as the center of the clusters. For cluster 1 the new centroid will be (2.5,11) and for cluster 2 it will be ((40+55+3)/3, (20+26+8)/3)=(32.67,18). With these new clusters we repeat the process again:
- Calcuate distance from clusters
- Assign each point to closest centroid
- Calculate new centroid of clusters
This will continue until the centroids do not change. After performing these operations 2 more times we get that the two centroids are (2.75,9) and (47.5,23). Cluster 1 consists of points 2 and 4 and cluster 2 consists of points 1 and 3. The figure below shows the points and how the initial centroid changes and consequently clusters change throughout the iterations.
The initialization of the centriods can affect the clusters.



