El preprocesamiento de los datos es de las etapas más importantes en cualquier proyecto de data science, principalmente porque es un proceso altamente difícil de automatizar y requiere de creatividad e intelecto humano para hacerse correctamente.
Esta etapa determinará la calidad final de tu modelo, por lo que no deberías temer en invertir el tiempo necesario.
Carga y análisis exploratorio de datos
Para esta ocasión usaremos una versión del dataset mnist en CSV que no está limpio, es decir, tiene datos faltantes e incongruencias que solucionaremos a continuación.
Empezaremos con un poco de análisis exploratorio, vamos a entender la densidad de los datos, donde gracias a matplotlib y seaborn podemos obtener una gráfica de la distribución de las etiquetas.
Para obtener información general del dataset podemos usar el método info que nos dará detalles de la estructura, su contenido y los tipos de datos que almacena.
train.info()<class'pandas.core.frame.DataFrame'>RangeIndex:27455 entries,0 to 27454Columns:784 entries, pixel1 to pixel784
dtypes:object(784)memory usage:164.2+MB
De la misma manera, podemos analizar específicamente cada columna con el atributo dtypes.
Podemos verificar si tenemos valores nulos en nuestra base de datos, esto nos dará información relacionada a negocio que puede ser valiosa, por lo que esta acción no solo ayuda a limpiar el dataset sino a comprender el posible origen del problema.
train.isnull().values.any()False
Podemos buscar datos duplicados con el método duplicated del dataframe, esto nos retornará una fila por cada elemento.
train[train.duplicated()]
Para borrar registros haremos uso del método drop que recibe como argumentos los index de los elementos a borrar.
El paso final será normalizar los datos para sintetizarlos desde el rango inicial al rango 0-1, para esto debemos convertir todos los datos en valores numéricos y luego aplicar la operación.
train = train.astype(str).astype(int)train = train /255test = test /255
Si verificamos el dataset limpio obtendremos 784 columnas con valores entre 0 y 1.
train.head()5 rows × 784 columns
Estos datos finales son mucho más procesables que los iniciales, por lo que tu rendimiento final se verá afectando positivamente.
Recuerda siempre dedicar una parte importante del tiempo de desarrollo en revisión y limpieza de datos para obtener resultados exponencialmente mejores.
Contribución creada por Sebastián Franco Gómez.
Intentas hacer el conteo de labels y te sale algo así?
escribe
sns.countplot(x='label', data=train)
En vez de
sns.countplot(train['label'])
gracias <3
y cual es la explicación de esto?
[
Para que puedan visualizar el balanceado de clases y además tengan una referencia numérica del porcentaje que representa cada una de las clases sobre el total.
Y así no debemos poner uno a uno los índices a eliminar.
Para este caso el drop se puede hacer usando
train.drop_duplicates(keep=False, inplace=True)
Leer archivos parquet con pandas:
Parquet es un format columnar comunmente usado en ambientes big data asi que espero les sirva saber que existe una función en pandas para leerlo
pd.read_parquet('/path/to/file')
Hola quisiera hacer una consulta con respecto a la calidad de las imágenes del dataset, la duda es tiene alguna relación el tamaño y la calidad de la imagen para tener mejores predicciones. Gracias!
¡Hola Stark!
Tienes una excelente pregunta sobre cómo afecta la resolución de la imagen en los resultados. En general, una mayor resolución de la imagen puede ofrecerte mejores resultados, ya que se pueden capturar más detalles y características. Sin embargo, debes tener en cuenta que a medida que aumenta la resolución, también aumenta el costo computacional necesario para procesarla. Piensa en una imagen como una matriz de píxeles: si la matriz es más grande, se requieren más operaciones matemáticas para recorrerla y analizarla.
Mi recomendación sería encontrar un equilibrio entre el costo computacional y la calidad del algoritmo. Al final, es probable que debas redimensionar las imágenes para que todas tengan el mismo tamaño de entrada para la red neuronal. Por lo tanto, es importante considerar el tipo de datos que se obtendrán en la aplicación real. Por ejemplo, si estás trabajando con imágenes de alta resolución en un proyecto de reconocimiento facial, es posible que desees mantener una resolución alta para capturar detalles finos. Sin embargo, si estás realizando detección de objetos en tiempo real en un dispositivo con recursos limitados, puede ser necesario reducir la resolución para obtener resultados rápidos y eficientes.
Además, las capas convolucionales y de pooling en los algoritmos de visión por computadora pueden ayudarte a reducir el tamaño de la imagen mientras se conservan las características principales. Estas capas permiten extraer características importantes y reducir la dimensionalidad de los datos sin perder información crítica.
Espero que esta explicación te haya resultado clara y útil. Si tienes más preguntas, ¡no dudes en hacerlas!
Saludos.
Excelente, muy clara la respuesta. Muchas gracias.
Saludos.
Ven, me podrías guiar según todo el código esta bien, no muestra error, pero no se por que se muestra así
Hola Nathiasolarte,
Pareciera que solo tuvieras una clase en el CSV, podrias revisar la ruta del CSV y confirmar que estes cargando el csv correcto.
Creo 🤔 que el profe normaliza los datos con "255" ya que en datos de imágenes donde un elemento tiende a tener el valor entre 0 y 255 para su color RGB.
Como en principio no conocemos qué otros string podrían haber en los datos hice una búsqueda automatizada con regex:
import re
r = re.compile(".*[A-Za-z].*")'''Este regex busca cualquier tipo de string que contenga una letra'''train = train.astype(str)for column in processed_train.columns: words =list(filter(r.match, processed_train[column].values))for word inwords: processed_train
= processed_train.drop(processed_train[processed_train[column]==word].index)
Me parece que hubo un pequeño detalle, primero se separó la variable objetivo
# 3️⃣ Verificamos que las columnas se hayan separado bien
print("Columnas del dataset:")
print(train.columns)
# 4️⃣ Mostramos las primeras filas para confirmar
print("\nPrimeras filas del dataset:")
print(train.head())
# 5️⃣ Creamos el gráfico de conteo de etiquetas
plt.figure(figsize=(10, 10))
sns.set_style("darkgrid")
sns.countplot(data=train, x="label")
plt.title("Distribución de clases en el dataset Sign MNIST")
plt.xlabel("Etiqueta")
plt.ylabel("Frecuencia")
plt.show()
Tengan en cuenta que la "Normalización" que se hace porque manejamos pixeles y sabemos cual es el máximo de este y que la imagen sigue siendo la misma después de , pero normalmente y de hecho incluso para este , para ser mas prácticos un MinMaxScaler viene bien , porque si subiéramos esto a producción eventualmente en el lado del cliente no va ver quien divida entre el numero máximo o encuentre como estandarizar , entonces es mejor hacer eso esto mas automático con pipelines que integren algún preprocesador