¿Cómo aplicar PCA para reducir la dimensionalidad de imágenes?
La reducción de dimensionalidad es una técnica crucial cuando trabajamos con conjuntos de datos grandes, y en el caso de imágenes, el uso de PCA (Análisis de Componentes Principales) es especialmente útil. Aquí te mostraré cómo hacerlo paso a paso utilizando Python.
¿Qué es PCA y cómo podemos usarlo?
PCA es un método estadístico que permite reducir la dimensionalidad de un conjunto de datos, manteniendo la mayor parte de la variabilidad presente en él. Esto se logra mediante la transformación de las variables originales en un nuevo conjunto de variables, llamadas componentes principales. He aquí cómo puedes implementarlo:
from sklearn.decomposition import PCA
# Instanciamos PCA para capturar el 50% de la varianza de los datoscaras_pca = PCA(n_components=0.5)# Ajustamos y transformamos nuestro conjunto de imágenescomponentes = caras_pca.fit_transform(imagenes)
¿Cómo visualizar los componentes?
Una parte importante del uso de PCA es la visualización de los componentes principales. Esto nos ayuda a entender cuántas componentes son necesarias para retener la información deseada.
import matplotlib.pyplot as plt
# Calculamos el número de filas y columnas para el gráficofilas =3columnas = caras_pca.n_components_ // filas
# Definimos la figurafig, ax = plt.subplots(filas, columnas, figsize=(12,6))for i, axi inenumerate(ax.flat):# Obtenemos la imagen correspondiente a la componente i componente_i = componentes[:, i].reshape(altura, ancho) axi.imshow(componente_i, cmap='gray') axi.set_title(f'Componente {i}') axi.axis('off')plt.show()
¿Qué sucede al ajustar el porcentaje de varianza explicada?
Modificar el porcentaje de varianza explicada nos permite ajustar la cantidad de componentes mantenidos. Esto es crucial para balancear entre precisión y eficiencia computacional.
# Por ejemplo, para capturar el 80% de la varianzacaras_pca_80 = PCA(n_components=0.8)componentes_80 = caras_pca_80.fit_transform(imagenes)# Con un 80% de varianza, obtenemos más componentes:# Requiere más tiempo de procesamiento pero mejora la calidad de la representación
¿Cómo afecta el porcentaje de información en los resultados?
Es interesante observar cómo el porcentaje de varianza afecta la cantidad de componentes y la representación de los datos. Al aumentar el porcentaje de información que queremos conservar, aumentamos el tiempo de computación y la complejidad.
caras_pca_999 = PCA(n_components=0.999)componentes_999 = caras_pca_999.fit_transform(imagenes)# Al graficar, notamos una representación más fiel, aunque con un costo computacional más alto
Las principales conclusiones son que con solo seis componentes puedes capturar el 50% de la información, utilizando cuarenta y cuatro componentes puedes capturar hasta el 80%, y si deseas casi el 100% de precisión, necesitas la mayoría de las imágenes como componentes. Con PCA, no solo puedes identificar patrones y rasgos clave en tus datos, sino que también mejoras la eficiencia del procesamiento, reduciendo la dimensionalidad de tus conjuntos de datos de manera efectiva.
Te animo a seguir explorando y experimentando con PCA y otras técnicas de reducción de dimensionalidad, ya que estas herramientas son fundamentales para el análisis de datos a gran escala y la comprensión de patrones complejos.
Únicamente con 44 componentes podemos recuperar el 80% de la información.
Interesante forma de utilizar PCA para imagenes. Tendré que repasar el curso, me gustó mucho
Muy bueno, pero yo también siento lo mismo ya que algunas cosas son difíciles de digerir a la primera
Oh vaya, ya no me siento tan solo ya que venía pensando lo mismo 😅
Deben de explicar un poco mejor cada termino del codigo. Uno no sabe si utilizar o no en otros problemas que tengamos. Además el mismo ejercicio se encuentra en internet.
Alguien me explica, por favor, cómo funciona el método " .fit()".
Gracias!!
PCA es un algoritmo para reducir las dimensiones. Basicamente lo que vimos en los modulos anteriores (autovectores, autovalores y despomposicion de la matriz por valores singulares SVD) es lo que usa el algoritmo PCA . Si recuerdas con el ejercicio de la "Cebra" usabamos los vectores y escalaes obtenidos de SVD para dibujarl la imagen sin necesidad de usar todos los valores de la matriz. Quiere decir que con un numero reducido de columnas en la matriz puedes obtener la mayor candiad de informacion. SVD regresa los valores ordenados por la magnitud de su varianza mayor varianza = mayor informacion.
Tambien recuerda que lo que hacen los algoritmos es reducir las dimensiones o el numero de componentes necesaria. En uno de los ejercicios se redujeron los datos de dos dimensiones X,Y a una sola "X" , es decir, todos los valores son proyectados sobre el eje X y se puede ver aun asi su dispersion.
GRACIAS!!
Para los que están el colab y tienen líos para montar las imagenes
caras = pd.DataFrame([])for root, dirs, files in os.walk(path):for file infiles: im = imageio.imread(root+"/"+file)/255 cara = pd.Series(im.flatten(), name=path) caras = caras.append(cara)fig, axes = plt.subplots(5,10, figsize=(15,8), subplot_kw ={'xticks':[],'yticks':[]}, gridspec_kw =dict(hspace =0.01, wspace =0.01))for i, ax inenumerate(axes.flat): ax.imshow(caras.iloc[i].values.reshape(112,92), cmap ="gray")
Muchas gracias por el aporte 👍
Hola, tengo dos preguntas:
Normalizamos la imagen 3 del sujeto 3, luego la mostramos, y ya. Después de eso no normalizamos el resto de imágenes en el dataframe y así (con rango de 0-255) las pasamos a PCA. Entonces la pregunta es, ¿porqué normalizar solo la primera imagen? (que es agregada después al dataframe sin normalizar)
Si PCA espera datos con media = 0 (centrados), ¿porqué aquí no los centramos como en la clase pasada?
También podemos explicar cada varianza
# Verificar la varianza explicada por cada componente principal
explained_variance_ratio = pca.explained_variance_ratio_cumulative_variance = np.cumsum(explained_variance_ratio)print("Varianza explicada por cada componente principal:")print(explained_variance_ratio)print("Varianza explicada acumulada:")print(cumulative_variance)
Uff! ¡Excelente clase! El profesor Sebastián explica muy bien.
Si el proposito de PCA es reducir dimensiones, ¿esto como aplica al ejemplo?. proyeccion.shape me sigue dando (400, 10304)
Proyección es el resultado de recuperar la información. El tamaño (400, 103004) respresenta que se tienen 400 imagenes de 103004 pixeles cada una.
Los datos de las imagenes se descompon en matrices, que incluyen toda la información, mas precisamente, a través del metodo SVD, que nos genera 3 matrices las cuales son U,M,V
Dependiendo del numero de componentes, es la cantidad de operaciones matriciales que debe realizar la computadora para llegar al dataFrame proyeccion
Si solo tenemos un componente, estamos realizando operaciones matriciales de las siguientes dimensiones
$\left[400, 1 \right] \times \left[ 400, 10304 \right] \times \left[ 1, 10304 \right]$
resultando en la matriz de (400,10304)
En cambio, con 150 componentes, la operación en cuanto a dimensiones de las matrices
$\left[400, 150 \right] \times \left[ 400, 10304 \right] \times \left[ 150, 10304 \right]$
resultando en la matriz de (400,10304)
Y usando toda la información, seria:
$\left[400, 400 \right] \times \left[ 400, 10304 \right] \times \left[ 400, 10304 \right]$
resultando en la matriz de (400,10304)
El resultado es una matriz en todos los casos con las mismas dimensiones, la reduccion de dimensiones es durante el proceso. Espero haber resuelto un poco de tus dudas.
Les comparto una aplicación de PCA que usé en un proyecto, es más simple que el análisis de rostros.
CONTEXTO: es una base de datos de ventas por tiendas, queríamos poder segmentar las tiendas para hacer un ranking entre grupos y poder emplear estrategias similares entre ellos. El vector X inicial tiene 13 variables (dimensiones).
Como se trata de aprendizaje no supervisado usamos el modelo de k-means, pero para conocer el número k ideal usamos PCA para ver la separación de clusters en 2 dimensiones.
CÓDIGO:
pca =PCA(n_components=2)X_pca= pca.fit_transform(X_scaled)# Clustering con K=4kmeans4 =KMeans(n_clusters=4, random_state=42, n_init='auto')df_cruce['Cluster4']= kmeans4.fit_predict(X_scaled)# Clustering con K=3kmeans3 =KMeans(n_clusters=3, random_state=42, n_init='auto')df_cruce['Cluster3']= kmeans3.fit_predict(X_scaled)# Crear figura con 2 subplots
fig, ax = plt.subplots(1,2, figsize=(12,6))# GráficoK=4ax[0].scatter(X_pca[:,0],X_pca[:,1], c=df_cruce['Cluster4'], cmap='viridis', s=60)ax[0].set_xlabel('Componente Principal 1')ax[0].set_ylabel('Componente Principal 2')ax[0].set_title('PCA de Clustering con k=4')# GráficoK=3ax[1].scatter(X_pca[:,0],X_pca[:,1], c=df_cruce['Cluster3'], cmap='viridis', s=60)ax[1].set_xlabel('Componente Principal 1')ax[1].set_ylabel('')ax[1].set_title('PCA de Clustering con k=3')plt.show()
RESULTADO:
Vamos a aplicar PCA (Análisis de Componentes Principales) para reducir la dimensionalidad de un conjunto de imágenes, lo cual es útil para:
Reducir el tamaño de almacenamiento.
Eliminar redundancia.
Visualizar datos complejos.
Extraer características para Machine Learning.
📦 Paso a paso en Python:
Primero cargamos las imágenes como ya lo hiciste, luego aplicamos PCA para reducirlas y reconstruimos algunas para ver el efecto.
✅ Código completo:
import pandas as pd
import matplotlib.pyplot as plt
import imageio.v2 as imageio
from glob import iglob
from sklearn.decomposition import PCA
# === 1. Cargar las imágenes ===
caras = []
for path in iglob('./imagenes/*/*.pgm'):
im = imageio.imread(path)
cara = pd.Series(im.flatten(), name=path)
caras.append(cara)
caras = pd.concat(caras, axis=1).T # Cada fila es una imagen
# === 2. Aplicar PCA ===
pca = PCA(n_components=50) # Usa 50 componentes principales
caras_pca = pca.fit_transform(caras)
# === 3. Reconstrucción aproximada de las imágenes ===
caras_reconstruidas = pca.inverse_transform(caras_pca)
for i in range(10):
# Original
axes[0, i].imshow(caras.iloc[i].values.reshape(112, 92), cmap='gray')
# Reconstruida
axes[1, i].imshow(caras_reconstruidas[i].reshape(112, 92), cmap='gray')
axes[0, 0].set_ylabel('Original', fontsize=12)
axes[1, 0].set_ylabel('Reconstruida', fontsize=12)
plt.suptitle('Reducción de Dimensiones con PCA', fontsize=14)
plt.tight_layout()
plt.show()
📉 Explicación:
n_components=50: Conservamos 50 dimensiones de las ~10,000 originales (112x92).
fit_transform: Calcula los ejes principales (autovectores) y proyecta las imágenes.
inverse_transform: Reconstruye la imagen original desde las componentes principales.
Eso significa que estás reteniendo el 92% de la información con solo 50 dimensiones.
Estos son los pasos de los videos de Juan Gabriel Gomila, para comparar otras enseñanzas:
Analisis de Componentes Principales - Paso a Paso
- Estandarizar los datos (para cada una de las m observaciones)
- Obtener los vectores y valores propios a partir de la matriz de covarianzas o de correlaciones o incluso la técnica de "singular vector descomposition"
- Ordenar los valores propios en orden descendente y quedarnos con los "p" que se correspondan a los "p" mayores y así disminuir el número de variables del dataset (p<m)
- Construir la matriz de proyección W a partir de los "p" vectores propios.
- Transformar el dataset original X a través de W para así obtener datos en el sibespacio dimensional "p", que será Y
Algo interesante para analizar es la relacion de Cantidad de Componentes Vs. Porcentaje de varianza explicada, la relacion es explonencial:
Excelente curso.
¿Que metodo me indica cuales son exactamente los principales componentes? :thinking:
El metodo PCA
JAJAJJAJAJAJAJA Seguro @Kevin-hernandez mi pregunta era sobre que propiedad de numpy o de la librería de algebra lineal me permitia ver el listado de las componentes de mayor a menor Autovalor, sin embargo me di cuenta que el orden es tal cual como lo habias ingresado (df_onehot.columns), de modo que lo he hecho así desde entonces: