Image Compression with K-Means K-Means clustering can be effective used for image compression. The core idea is to reduce the number of colors in an image. Instead of storing the exact RGB value for every pixel, we can group similar colors into clusters. Each pixel is then represented by the color of its cluster's centroid, significantly reducing the data size while preserving the overall visual quality.
The process involves the following steps:
Load the image and convert it into a numerical format.
Reshape the image data into a 2D array where each row represents a single pixel's RGB values.
Apply the K-Means algorithm to cluster these color vectors. The number of clusters determines the size of the new color palette.
Replace each pixel's original color with the color of its assigned cluster centroid.
Reshape the data back into the original image dimensions and save the compressed image.
Here is a Python implementation using Scikit-learn, NumPy, and Matplotlib:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from matplotlib.image import imread
# Load the image
image_path = 'sample_image.jpg'
original_image = imread(image_path)
# Display the original image
plt.figure(figsize=(10, 5))
plt.subplot(1, 2, 1)
plt.imshow(original_image)
plt.title('Original Image')
plt.axis('off')
# Resize the image to speed up processing (optional)
resized_image = original_image[::3, ::3, :]
# Reshape the image data for clustering
# Each row is a pixel, with 3 columns for R, G, B values
pixel_data = resized_image.reshape(-1, 3)
# Define the number of colors (clusters) for the compressed image
num_colors = 64
# Initialize and train the K-Means model
kmeans_model = KMeans(n_clusters=num_colors, random_state=42)
pixel_labels = kmeans_model.fit_predict(pixel_data)
# Get the RGB values of the cluster centroids
cluster_centers = kmeans_model.cluster_centers_.astype(int)
# Create the compressed image by mapping each pixel to its cluster's color
compressed_pixels = cluster_centers[pixel_labels]
compressed_image = compressed_pixels.reshape(resized_image.shape)
# Convert data type to uint8 for image saving
compressed_image = compressed_image.astype(np.uint8)
# Display the compressed image
plt.subplot(1, 2, 2)
plt.imshow(compressed_image)
plt.title(f'Compressed Image ({num_colors} colors)')
plt.axis('off')
plt.show()
# Save the compressed image
output_path = 'compressed_image.jpg'
plt.imsave(output_path, compressed_image)
print(f"Compressed image saved to {output_path}")
Student Grouping Based on Academic Performance K-Means clustering is also valuable for segmenting data into distinct groups. A practical example is grouping students based on their academic scores across multiple subjects. This can help educators identify different performance profiles and tailor their teaching strategies accordingly.
The wrokflow is as follows:
Collect and load the student data, including scores for various subjects.
Preprocess the data by selecting relevant features (scores) and handling any missing values.
Choose the number of clusters (e.g., to create four distinct groups).
Train the K-Means model on the score data.
Assign each student to a cluster and analyze the characteristics of each group.
The following code demonstrates this process using a sample dataset:
import pandas as pd
import numpy as np
from sklearn.cluster import KMeans
import matplotlib.pyplot as plt
# Load the student data from a CSV or Excel file
# Replace 'student_scores.csv' with your actual data file path
data_path = 'student_scores.csv'
student_data = pd.read_csv(data_path)
# Select the columns containing the scores for clustering
score_columns = ['Math', 'Science', 'English', 'History']
features = student_data[score_columns].fillna(0).values
# Define the number of student groups to create
num_groups = 4
# Initialize and train the K-Means model
kmeans_model = KMeans(n_clusters=num_groups, random_state=42)
cluster_assignments = kmeans_model.fit_predict(features)
# Get the coordinates of the cluster centroids
cluster_centroids = kmeans_model.cluster_centers_
# Add the cluster assignment to the original DataFrame for analysis
student_data['Group'] = cluster_assignments
# Print the cluster centroids to understand the average score profile of each group
print("Cluster Centroids (Average Scores per Group):")
print(pd.DataFrame(cluster_centroids, columns=score_columns))
# Display the students in each group
for i in range(num_groups):
group_members = student_data[student_data['Group'] == i]['Name'].tolist()
print(f"
Group {i+1} Members: {group_members}")
# Visualize the clustering result
plt.figure(figsize=(10, 6))
plt.scatter(student_data.index, cluster_assignments, c=cluster_assignments, cmap='viridis', s=50, alpha=0.7)
plt.title('Student Grouping Based on Academic Scores')
plt.xlabel('Student Index')
plt.ylabel('Assigned Group')
plt.yticks(range(num_groups))
plt.grid(True, linestyle='--', alpha=0.6)
plt.show()