johan Stever Rodriguez Molina
la mejor manera de conseguir el data set es:
import sklearn.datasets data= sklearn.datasets.fetch_olivetti_faces()
automaticamente se descarga el dataset.
Luis Raúl González Romo
Luis Angel José Portillo Arévalo
¿Qué es el análisis de componentes principales?
El análisis de componentes principales (PCA, por sus siglas en inglés) es una técnica invaluable en el mundo del procesamiento de datos para reducir la cantidad de dimensiones con las que trabajamos. Frecuentemente, enfrentamos conjuntos de datos con muchas variables, y PCA nos ayuda a conservar el 80% de la información más relevante con menos variables. En síntesis, simplifica nuestros datos sin perder demasiada información esencial.
¿Cómo preparar datos de imágenes para PCA?
Para ilustrar cómo aplicar PCA, veamos un ejemplo con imágenes. Utilizaremos un conjunto de datos de rostros del laboratorio Olivetti, creado entre 1992 y 1994 en los laboratorios de Cambridge.
Paso 1: Importar librerías necesarias
Utilizaremos librerías de Python como numpy, matplotlib, y pandas para realizar las operaciones requeridas:
import numpy as np import matplotlib.pyplot as plt import pandas as pd
Paso 2: Leer y normalizar las imágenes
Primero, cargamos las imágenes desde un directorio específico. Luego, normalizamos los valores de las imágenes dividiéndolos por 255, el valor máximo posible en una imagen en escala de grises.
image = np.random.rand(112, 92) # ejemplo de una imagen image_normalizada = image / 255.0
Paso 3: Visualización sin ejes
Para graficar estas imágenes sin mostrar los ejes cartesianos, los configuramos así:
fig, axs = plt.subplots(1, 2, figsize=(12, 12)) axs[0].imshow(image, cmap='gray') axs[1].imshow(image_normalizada, cmap='gray') for ax in axs: ax.set_xticks([]) ax.set_yticks([]) plt.show()
¿Cómo gestionar múltiples imágenes?
Paso 1: Leer múltiples imágenes
Configuramos un DataFrame para conservar los datos de cada imagen a medida que las leemos. Esto requiere recorrer los archivos de imágenes disponibles.
from glob import glob imagenes = glob('imagenes/*') caras = pd.DataFrame() for archivo in imagenes: img = plt.imread(archivo).flatten() # aplanar la imagen caras = caras.append([img], ignore_index=True)
Paso 2: Visualización de un subconjunto de imágenes
Podemos mostrar un conjunto de imágenes seleccionando un número de individuos y el número de tomas para cada uno:
fig, axs = plt.subplots(5, 10, figsize=(15, 8)) for i, ax in enumerate(axs.flatten()): img = caras.iloc[i].values.reshape(112, 92) # reconstruir la forma original ax.imshow(img, cmap='gray') ax.set_xticks([]) ax.set_yticks([]) plt.subplots_adjust(wspace=0.1, hspace=0.01) plt.show()
Este setup nos permite tener una vista preliminar del conjunto de datos con el que trabajaremos en PCA.
Reflexiones finales
El análisis de componentes principales se convertirá en un aliado fundamental para el análisis y procesamiento de datos, especialmente cuando se trabaja con imágenes o datasets de alta dimensionalidad. Además, el uso correcto de librerías como numpy y pandas optimiza la preparación y limpieza de datos. ¡Vamos a seguir explorando el potencial de estas herramientas y a comprender a fondo sus aplicaciones!
johan Stever Rodriguez Molina
la mejor manera de conseguir el data set es:
import sklearn.datasets data= sklearn.datasets.fetch_olivetti_faces()
automaticamente se descarga el dataset.
Luis Raúl González Romo
Luis Angel José Portillo Arévalo
Nicolás Rodas Rios
Mauro Benito Montoya Arenas
Gracias amigo, estaba teniendo problemas con eso.
NICOLAS ZAPATA RAMIREZ
Muchas gracias amigo, justo estaba atascado en lo mismo.
María José Medina
Aunque si bien puede ser más fácil descargar las imágenes de la libreria de sklearn, con este código aprendemos a cargar nuestros propios datasets de imágenes, vale la pena entenderlo.
Cristian David Alegria Cardona
Isaac Bryan Ascanoa Roncall
Muchas gracias por tu solucion tuve muchos problemas con la clase del profe que se demoraba mucho y el tamaño de las imagenes no las leia. Este resulto mas sencillo.
Mauro Benito Montoya Arenas
“imageio” ya esta obsoleta. En lugar de eso se puede usar:
import imageio.v2 as imageio
María Eugenia Pereira Chévez
o
import imageio.v3 as iio
Rodrigo Urquizo Yepez
Para no ver los ejes cartesianos pueden usar tambien esto: ax.set_axis_off()
Luis Angel José Portillo Arévalo
tendria que ser: ax[0].axis('off') ax[1].axis('off')
basicamente remover individualmente el axis de cada subplot, tambien usando un ciclo
Luis Angel José Portillo Arévalo
Para los que no saben usar el dataset de scikit learn que compartio johanR, con ese dataset no hay necesidad de usar imageio para cargar las imagenes, porque ya al hacer:
import sklearn.datasets data= sklearn.datasets.fetch_olivetti_faces()
Alli se descarga automaticamente, como dice johanR, todo el dataset en la variable data
tampoco es necesario normalizar los valores porque ya en el dataset estan normalizados, lo unico que se necesitaria es consumirlos.
la variable data contiene el dataset, pero los valores estarian dentro de data.data.
Ademas, data.data es un array almacena individualmente cada imagen en cada posicion del mismo.
La imagen esta almacenada como una tira de valores (todos los valores en una sola dimension), como necesitamos es una matriz, le aplicaremos un reshape.
Las imagenes tienen 4096 valores en una dimension, el cual es un tamaño de 64 x 64 en dos dimensiones, entonces por ejemplo hariamos algo asi:
imagen_1 = data.data[0].reshape(64, 64) imagen_2 = data.data[1].reshape(64, 64)
De esa forma estarian manipulando la misma matriz normalizada del profesor, por ejemplo para mostrar la imagen numero 6 del dataset seria asi:
plt.imshow(data.data[5].reshape(64,64), cmap='gray')
María José Medina
En el minuto 10:05, para saber las dimensiones a las que se debe volver a dar forma basta con ejecutar:
im.shape
Carli Code
ProfesorPor qué especifica que el tipo de dato debería ser "np.uint8"?
Rodrigo Urquizo Yepez
Hola, todo parte de que una computadora solo lee 0 y 1, algo que seguro sabes.Cuando hablamos de un bit las unicas opciones son o un cero o un uno,es decir dos posibilidades, si tenemos dos bits tendriamos 10,01,00 y 11, es decir 4 (2^2) posibilidades.Cuando hablamos de 8 bits tenemos en total 256 (2^8) posibilidades, ahora al hacer np.uint8 le estamos diciendo a numpy que nuestros datos seran de 8 bits y esto es porque al trabajar con una imagen en escala de grises, la intensidad de cada pixel tiene un valor numerico entre 0 y 255,es decir 256 posibilidades. Como dato el 0 es negro y el 255 blanco.
Carli Code
ProfesorTodo está mas claro ahora, muchísimas gracias!
Diego González Castellanos
Para los que están en colab y tiene lios para montar las imagenes
caras = pd.DataFrame([]) for root, dirs, files in os.walk(path): for file in files: 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 in enumerate(axes.flat): ax.imshow(caras.iloc[i].values.reshape(112,92), cmap = "gray")
Israel Guevara
Para poder abrir la imagen en google colab yo usé las siguientes líneas de código, además de subir la carpeta a mi drive
<code> from google.colab import drive drive.mount('/content/drive') %cd "/content/drive/MyDrive/Colab Notebooks/Curso AL aplicada a machine learning/Img/imagenes/s3" im = imageio.imread("./3.pgm")
Daniel Andres Rojas Paredes
Cuando preparamos datos para PCA, es crucial que estén normalizados a un rango como [0,1] o [-1,1]. Esto se debe a que PCA busca las direcciones de máxima varianza en los datos, y si las características tienen diferentes escalas, algunas pueden dominar el análisis, distorsionando los resultados. Al estandarizar, aseguramos que todas las características contribuyan equitativamente, facilitando la identificación de patrones y la reducción dimensional de manera efectiva.
Paolo Joaquin Pinto Perez
Solucion para los que utilizan vscode + mac!!
from glob import iglob caras = pd.DataFrame([]) for path in iglob("./imagenes/*/*.pgm"): im = imageio.imread(path) cara = pd.Series(im.flatten(),name=path) caras = pd.concat([caras, cara], axis=1) fix, axes = plt.subplots(5, 10, figsize=(15,8), subplot_kw={'xticks': [],'yticks':[]}, gridspec_kw=dict(hspace=0.01,wspace=0.01)) for i,ax in enumerate(axes.flat): ax.imshow(caras.T.iloc[i].values.reshape(112,92), cmap = 'gray') #ax.imshow(caras.T.iloc[i].values.reshape(112, 92).T, cmap='gray')
BRANDO JESUS AUCANCELA LOZANO
Algunas opciones para poder cargar los datos:
import sklearn.datasets im1= sklearn.datasets.fetch_olivetti_faces()
im3 = imageio.imread('imagenes/s3/3.pgm')
im2 = imageio.imread(r'D:\VS Code\imagenes\s7\7.pgm')
Carlos José Manosalva
Así lo hice yo:
from sklearn.datasets import fetch_olivetti_faces data = fetch_olivetti_faces() caras = [] for index in range(50): cara = pd.Series(data.data[index].reshape(64, 64).flatten(), name = index) 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)) caras = pd.DataFrame(caras) for i, ax in enumerate(axes.flat): ax.imshow(caras.iloc[i].values.reshape(64,64), cmap = 'gray')
Mario Alexander Vargas Celis
El PCA en imágenes es una técnica poderosa para reducir el tamaño y la complejidad de una imagen sin perder (demasiada) información relevante. En lugar de operar sobre datos tabulares, se aplica sobre los pixeles de la imagen, que pueden tratarse como vectores de alta dimensión.
📌 ¿Por qué aplicar PCA a imágenes?
🖼️ ¿Cómo se aplica?
Una imagen a color (RGB) es una matriz 3D: alto × ancho × 3 canales. Se puede aplicar PCA por canal o convertirla a escala de grises y luego aplicar PCA sobre la matriz 2D resultante.
🧪 Ejemplo Práctico: PCA aplicado a una imagen con Python
import numpy as np import matplotlib.pyplot as plt from sklearn.decomposition import PCA from skimage.color import rgb2gray from skimage.io import imread
# 1. Cargar imagen y convertir a escala de grises img = imread('tu_imagen.jpg') # Reemplaza con una ruta válida gray_img = rgb2gray(img)
# 2. Visualizar la imagen original plt.imshow(gray_img, cmap='gray') plt.title("Imagen Original") plt.axis("off") plt.show()
# 3. Aplicar PCA n_components = 50 # puedes cambiar este valor pca = PCA(n_components=n_components) transformed = pca.fit_transform(gray_img) reconstructed = pca.inverse_transform(transformed)
# 4. Mostrar imagen reconstruida plt.imshow(reconstructed, cmap='gray') plt.title(f"Reconstruida con {n_components} componentes") plt.axis("off") plt.show()
# 5. Comparar varianza explicada print(f"Varianza explicada acumulada: {np.sum(pca.explained_variance_ratio_):.4f}")
📉 Resultado:
🎯 Aplicaciones reales
Franco Sosa
HAY FORMA DE PREGUNTAR ALGO AL PROFESOR O SOLAMENTE A COMAPNEROS MEDIANTE LA PESTANA DE "PREGUNTAS"?
Yonaikel M. Delgado N.
en vs code no me detecta el comando "astype" para transformar el tipo de datos y por ello me sale error en la celda
Dionicio Perez
Importa la libreria al inicio de la siguiente forma
import imageio.v2 as imageio
¿Podrìas orientarme como cargarlo? Por favor.
Agregue esta parte:
from sklearn.datasets import fetch_olivetti_faces
y luego:
data = fetch_olivetti_faces() im = imageio.imread(data) im = im.astype(np.uint8) print(im)
No entiendo que salió mal. como que me carga el dataset y no las imágenes
Para los que no saben usar el dataset, no hay necesidad de usar imageio para cargar las imagenes, porque ya al hacer:
import sklearn.datasets data= sklearn.datasets.fetch_olivetti_faces()
Alli se descarga automaticamente como dice johanR todo el dataset en la variable data
tampoco es necesario normalizar los valores porque ya en el dataset estan normalizados, lo unico que se necesitaria es consumirlos.
la variable data contiene el dataset, pero los valores estarian dentro de data.data.
Ademas, data.data es un array almacena individualmente cada imagen en cada posicion del mismo.
La imagen esta almacenada como una tira de valores (todos los valores en una sola dimension), como necesitamos es una matriz, le aplicaremos un reshape.
Las imagenes tienen 4096 valores en una dimension, el cual es un tamaño de 64 x 64 en dos dimensiones, entonces por ejemplo hariamos algo asi:
imagen_1 = data.data[0].reshape(64, 64) imagen_2 = data.data[1].reshape(64, 64)
De esa forma estarian manipulando la misma matriz normalizada del profesor, por ejemplo para mostrar la imagen numero 6 del dataset seria asi:
plt.imshow(data.data[5].reshape(64,64), cmap='gray')
Un pequeño aporte de mi parte:
Muchos se daran cuenta que al correr el codigo
from glob import iglob caras = pd.DataFrame([]) for path in iglob(".\\imagenes\\*\\*.pgm"): im = imageio.imread(path) cara = pd.Series(im.flatten(), name = path) caras = caras.append(cara)
Les generará intriga el mensaje de advertencia en la consola:
<ipython-input-10-ec2cdce44f6c>:7: FutureWarning: The frame.append method is deprecated and will be removed from pandas in a future version. Use pandas.concat instead. caras = caras.append(cara)
Este mensaje es basicamente que usar frame.append() va a quedar obsoleto en un futuro, por lo que usar pandas.concat se ve como una solución atractiva al mensaje de advertencia, sin embargo rapidamente nos damos cuenta que pandas.concat nos genera un resultado distinto a frame.append() por lo que el codigo deja de funcionar.
Les comparto mi solución sencilla a lo anterior.
from glob import iglob caras = pd.DataFrame([]) for path in iglob(".\\imagenes\\*\\*.pgm"): im = imageio.imread(path) cara = pd.Series(im.flatten(), name = path) caras = pd.concat([caras, cara], axis=1) caras = caras.T
Espero les sirva!
Para los que esten usando google colab y no quieran complicarse descargando las imagenes, el codigo quedaria así:
<import sklearn.datasets data = sklearn.datasets.fetch_olivetti_faces() caras = pd.DataFrame([]) for i in range(50): cara = data.data[i].reshape(64,64) caraa = pd.Series(cara.flatten(), name=i) caras = pd.concat([caras, caraa], axis=1) caras = caras.T 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 in enumerate(axes.flat): ax.imshow(caras.iloc[i].values.reshape(64,64),cmap='gray') >
Si estan utilizando el caras.append() deben eliminar el caras.T y listo