Eigenfaces: cómo PCA reconstruye 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)
¿Se puede representar un rostro con mucha menos información sin perder su esencia? Con PCA y eigenfaces la respuesta es sí. A partir de un conjunto de imágenes, los componentes principales se vuelven “caras fantasma” que capturan variaciones globales como la iluminación, y rasgos locales como la forma de la nariz, la línea de la mandíbula o la posición de los ojos. Con unas pocas eigenfaces, es posible una reconstrucción fiel que impulsa el reconocimiento facial y la compresión de imágenes.
¿Qué son los eigenfaces con PCA y para qué sirven?
Los eigenfaces aparecen al aplicar PCA a rostros: cada componente principal es una “cara” que recoge una porción de la variación del conjunto. El primero suele reflejar la iluminación general; los siguientes, rasgos faciales específicos.
- Idea central: cualquier rostro se expresa como combinación ponderada de eigenfaces.
- Ahorro: usar solo los componentes más importantes conserva gran detalle con mucha menos información.
- Aplicaciones: reconocimiento facial y compresión al reducir la dimensionalidad sin perder estructura clave.
¿Cómo representan un rostro con combinación ponderada?
- Cada peso indica cuánto aporta una eigenface al rostro final.
- Con pocos componentes se pierde textura fina: barba, bigote o lentes pueden atenuarse.
- Con más componentes, la reconstrucción se acerca mucho a la imagen original.
¿Cómo implementar PCA con Olivetti faces en Google Colab?
Se trabaja en Google Colab con NumPy, Matplotlib y Scikit-learn, usando el dataset Olivetti faces. Las imágenes son de 64 × 64 píxeles (4096 características) y en total hay 400 rostros.
¿Cómo preparar los datos y dimensiones 64x64?
import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import fetch_olivetti_faces
faces = fetch_olivetti_faces(shuffle=True)
X = faces.data # matriz (400, 4096)
print(X.shape)
h, w = faces.images.shape[1], faces.images.shape[2] # 64, 64
- X tiene forma (400, 4096): 400 imágenes, 4096 píxeles por rostro.
- h, w = 64, 64 permiten el reshape para visualizar.
¿Cómo ajustar, comprimir y reconstruir con componentes principales?
pca = PCA(n_components=150)
pca.fit(X) # ajusta PCA sobre todas las caras
cara_original = X[0] # primera cara
descriptor = pca.transform([cara_original]) # compresión a 150 dim
def reconstruir_con_k_componentes(K):
cara_reducida = descriptor[:, :K]
if K < pca.n_components_:
padding = np.zeros((1, pca.n_components_ - K))
cara_reducida = np.concatenate([cara_reducida, padding], axis=1)
cara_k = pca.inverse_transform(cara_reducida)
return cara_k.reshape(h, w)
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('K=10')
axes[2].imshow(reconstruir_con_k_componentes(50), cmap='gray'); axes[2].set_title('K=50')
axes[3].imshow(reconstruir_con_k_componentes(150), cmap='gray'); axes[3].set_title('K=150')
plt.show()
- Flujo de trabajo con Scikit-learn: fit para hallar componentes, transform para comprimir una cara, inverse_transform para reconstruir.
- Detalle práctico: si usas menos que 150, se hace “padding” con ceros para completar antes del inverse_transform.
- Visualización con subplots, imshow y cmap='gray' para comparar calidad.
¿Qué resultados y aprendizajes clave ofrece la reconstrucción?
Con K=10 componentes, la cara se distingue pero se pierden detalles finos como barba, bigote o lentes. Con K=50, la definición mejora de forma clara. Con K=150, la reconstrucción es muy similar a la original, usando solo una fracción de las 4096 dimensiones. Al subir a K=300, el resultado es prácticamente igual a la imagen original.
- Reducción de dimensionalidad efectiva: mucha fidelidad con menos datos.
- Trade-off controlado: más componentes, más detalle; menos componentes, más compresión.
- Parámetros clave: número máximo de componentes igual a 4096, elección típica de 150 para buen balance.
- Habilidades practicadas: fit, transform, inverse_transform, reshape, “padding” con ceros, comparación visual con Matplotlib.
- Keywords: eigenfaces, PCA, componentes principales, reconocimiento facial, compresión de imágenes, Olivetti faces, Scikit-learn, NumPy.
¿Te animas a replicarlo con otros rostros? Prueba con 10, 50, 100 y 150 componentes: cuenta qué detalles se pierden o conservan y comparte tus resultados en los comentarios.