Eigenfaces: cómo PCA comprime rostros
Clase 7 de 12 • Curso Avanzado de Álgebra Lineal y Machine Learning: PCA y SVD
Contenido del curso
Eigen-Análisis
Reducción de Dimensionalidad con PCA
Descomposición en Valores Singulares (SVD)
¿Quieres comprimir y reconstruir rostros con alta fidelidad usando una fracción de los píxeles? Con eigenfaces y reducción de dimensionalidad mediante PCA en Python, es posible representar una cara como combinación de componentes principales y recuperar gran parte de los detalles con muy poca información. Ideal para reconocimiento facial y compresión de imágenes.
¿Qué son los eigenfaces y cómo reduce PCA un rostro?
Los componentes principales de PCA aplicados a imágenes de rostros no son ejes abstractos: son caras base o eigenfaces que capturan patrones de variación. El primer componente suele reflejar la iluminación general. Los siguientes concentran rasgos como nariz, mandíbula y ojos.
- Un rostro se expresa como una combinación ponderada de eigenfaces.
- Usando solo los componentes más importantes, se reconstruye la imagen con gran calidad.
- Base de reconocimiento facial y compresión: menos datos, alta fidelidad.
¿Qué datos y dimensiones se manejan?
Se trabaja con las caras de Olivetti: 400 imágenes en escala de grises de 64×64 píxeles. Al vectorizar, cada imagen tiene 4096 características. La matriz de datos queda en forma (400, 4096).
- Matriz de trabajo: X con forma (n_imágenes, n_pixeles).
- Altura y ancho: h = 64, w = 64.
- Configuración típica: 150 componentes para empezar; también se prueba con 300.
¿Cómo preparar los datos de Olivetti y configurar PCA en Python?
En Google Colab, se importan NumPy, Matplotlib y PCA de Scikit-learn, además del dataset de Olivetti con fetch_olivetti_faces y shuffle.
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import fetch_olivetti_faces
faces_data = fetch_olivetti_faces(shuffle=True)
X = faces_data.data # Matriz (400, 4096)
h, w = faces_data.images.shape[1], faces_data.images.shape[2] # 64, 64
pca = PCA(n_components=150)
pca.fit(X) # Ajuste sobre todo el conjunto
¿Qué significan fit, transform y fit_transform?
- fit: encuentra los componentes principales del conjunto. Se usa para ajustar el modelo a todas las imágenes.
- transform: proyecta nuevos datos en esos componentes ya aprendidos.
- fit_transform: ajusta y proyecta en el mismo paso para todos los datos. Aquí se prefiere separar: fit sobre todas las caras y transform sobre una cara específica.
Ejemplo con una cara:
cara_original = X[0]
cara_comprimida = pca.transform([cara_original]) # Proyección en 150 componentes
¿Cómo reconstruir y visualizar con k componentes diferentes?
La idea es tomar los primeros k componentes, rellenar con ceros hasta 150 si hace falta y aplicar inverse_transform para volver al espacio de píxeles.
def reconstruir_con_k_componentes(k):
cara_reducida = cara_comprimida[:, :k]
if k < 150: # Si luego usas 300, ajusta también aquí.
padding = np.zeros((1, 150 - k))
cara_reducida = np.c_[cara_reducida, padding]
cara_k_reconstruida = pca.inverse_transform(cara_reducida)
return cara_k_reconstruida.reshape(h, w)
Visualización con subplots, imshow, cmap='gray' y reshape para comparar original vs. reconstrucciones con k = 10, 50, 150:
fig, axes = plt.subplots(1, 4, figsize=(16, 5))
axes[0].imshow(cara_original.reshape(h, w), cmap='gray')
axes[0].set_title('Original')
axes[1].imshow(reconstruir_con_k_componentes(10), cmap='gray')
axes[1].set_title('Reconstrucción k=10')
axes[2].imshow(reconstruir_con_k_componentes(50), cmap='gray')
axes[2].set_title('Reconstrucción k=50')
axes[3].imshow(reconstruir_con_k_componentes(150), cmap='gray')
axes[3].set_title('Reconstrucción k=150')
plt.show()
- Con k=10: se diferencian rasgos globales, pero se pierden detalles como barba, bigote y lentes.
- Con k=50: mejora notable en contornos y textura.
- Con k=150: la imagen es muy similar a la original usando solo una fracción de 4096 píxeles.
- Al subir a k=300 (cambiando también la configuración y la función): la reconstrucción es prácticamente igual a la original.
¿Te animas a experimentar? Prueba con otro conjunto de rostros, incluso fotos de amistades o familia, y cuéntanos qué detalles se pierden o conservan con 10, 50, 100 o 150 componentes. ¿Con cuántos logras una reconstrucción satisfactoria? Deja tus resultados y observaciones en los comentarios. En la próxima sesión: interpretarás qué píxeles pesan más en cada eigenface con los componentes principales.