Concepto clave
Containerizar un pipeline de preprocesamiento significa empaquetar todo el codigo, dependencias y configuraciones necesarias para transformar datos crudos en un formato listo para modelos de ML, dentro de un contenedor Docker. Imagina que eres un chef preparando un plato complejo: en lugar de llevar todos tus utensilios y ingredientes a cada cocina diferente, preparas un kit de cocina portatil (el contenedor) que contiene exactamente lo que necesitas, garantizando que el plato salga igual sin importar donde lo prepares. Esto elimina el clasico problema del "en mi maquina funciona" y permite reproducibilidad total.
Para cientificos de datos, esto es crucial porque los pipelines de preprocesamiento suelen involucrar librerias especificas (como pandas, scikit-learn), versiones de Python, y archivos de configuracion. Al containerizarlo, aseguras que cualquier miembro del equipo o sistema de produccion ejecute exactamente los mismos pasos, desde la limpieza de datos hasta la normalizacion. Ademas, facilita la integracion con orquestadores como Kubernetes para escalar el procesamiento de grandes volumenes de datos.
Como funciona en la practica
Vamos a containerizar un pipeline simple de preprocesamiento para datos de ventas. Supongamos que tienes un script en Python que lee un archivo CSV, limpia valores nulos, normaliza columnas numericas y guarda el resultado. Sin Docker, dependes de que el entorno tenga las librerias correctas instaladas. Con Docker, creas un entorno aislado que siempre funciona igual.
Paso a paso: primero, escribes un Dockerfile que define la imagen del contenedor. Esto incluye una imagen base (por ejemplo, Python 3.9), la instalacion de dependencias desde un archivo requirements.txt, la copia de tu codigo y datos, y el comando para ejecutar el pipeline. Luego, construyes la imagen con docker build y la ejecutas con docker run. El contenedor ejecutara tu script de preprocesamiento de manera aislada, y puedes compartir la imagen o ejecutarla en cualquier maquina con Docker instalado.
Codigo en accion
Aqui tienes un ejemplo funcional. Primero, el script de preprocesamiento (preprocess.py):
import pandas as pd
from sklearn.preprocessing import StandardScaler
import sys
def preprocess_data(input_path, output_path):
# Leer datos
df = pd.read_csv(input_path)
# Limpiar valores nulos
df = df.dropna()
# Normalizar columnas numericas
numeric_cols = df.select_dtypes(include=['float64', 'int64']).columns
scaler = StandardScaler()
df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
# Guardar resultado
df.to_csv(output_path, index=False)
print(f"Preprocesamiento completado. Datos guardados en {output_path}")
if __name__ == "__main__":
if len(sys.argv) != 3:
print("Uso: python preprocess.py ")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
preprocess_data(input_file, output_file)Ahora, el Dockerfile para containerizarlo:
# Usar una imagen base de Python
FROM python:3.9-slim
# Establecer el directorio de trabajo
WORKDIR /app
# Copiar archivos de dependencias
COPY requirements.txt .
# Instalar dependencias
RUN pip install --no-cache-dir -r requirements.txt
# Copiar el codigo y datos
COPY preprocess.py .
COPY sales_data.csv .
# Comando para ejecutar el pipeline
CMD ["python", "preprocess.py", "sales_data.csv", "processed_data.csv"]El archivo requirements.txt contiene: pandas==1.5.3 scikit-learn==1.2.2. Para construir y ejecutar: docker build -t ml-preprocess . y luego docker run ml-preprocess.
Errores comunes
- No incluir todos los archivos necesarios en el Dockerfile: Si olvidas copiar el archivo de datos (como sales_data.csv), el contenedor fallara al ejecutarse. Solucion: usa COPY para todos los archivos esenciales, o monta volúmenes para datos dinamicos.
- Usar imagenes base demasiado grandes: Imagenes como python:latest pueden ser innecesariamente grandes, ralentizando la construccion y despliegue. Solucion: usa versiones slim (por ejemplo, python:3.9-slim) para reducir el tamaño.
- No manejar permisos de archivos: En algunos sistemas, el contenedor puede no tener permisos para leer/escribir archivos. Solucion: ajusta permisos en el Dockerfile con RUN chmod o usa usuarios no root.
- Ignorar el cache de Docker: Cambios pequeños en el codigo pueden no reflejarse si no se reconstruye correctamente. Solucion: ordena las instrucciones en el Dockerfile para que las capas que cambian frecuentemente (como COPY del codigo) esten al final.
Checklist de dominio
- He escrito un Dockerfile que incluye una imagen base apropiada, instalacion de dependencias, y copia de codigo y datos.
- Mi contenedor ejecuta exitosamente el pipeline de preprocesamiento sin errores de dependencias.
- He probado el contenedor en al menos dos entornos diferentes (por ejemplo, mi maquina local y un servidor) para verificar portabilidad.
- He optimizado el tamaño de la imagen usando capas eficientes y versiones slim.
- He documentado los pasos para construir y ejecutar el contenedor en un README.
- He manejado archivos de entrada/salida de forma que el contenedor pueda recibir parametros o usar volúmenes.
- He integrado el contenedor en un flujo simple, como ejecutarlo desde un script de shell o un cron job.
Containeriza un pipeline de preprocesamiento para datos de texto
En este ejercicio, containerizaras un pipeline de preprocesamiento para datos de texto que limpia y tokeniza un archivo CSV. Sigue estos pasos:
- Crea un script Python llamado
text_preprocess.pyque:- Lea un archivo CSV con una columna llamada "texto".
- Limpie el texto (por ejemplo, convertir a minusculas, eliminar puntuacion).
- Tokenice el texto usando la libreria nltk o split simple.
- Guarde el resultado en un nuevo archivo CSV con una columna "tokens".
- Crea un archivo
requirements.txtcon las dependencias necesarias (por ejemplo, pandas, nltk). - Escribe un Dockerfile que:
- Use una imagen base de Python 3.9-slim.
- Instale las dependencias desde requirements.txt.
- Copia el script y un archivo de datos de ejemplo (por ejemplo,
text_data.csv). - Ejecute el script al iniciar el contenedor.
- Construye la imagen Docker con el tag
text-preprocess. - Ejecuta el contenedor y verifica que genere el archivo de salida correctamente.
- Opcional: Modifica el Dockerfile para aceptar el nombre del archivo de entrada y salida como argumentos.
- Recuerda incluir nltk.download('punkt') en tu script si usas nltk para tokenizacion, ya que necesita datos adicionales.
- Usa el comando CMD en el Dockerfile con parametros para hacer el contenedor mas flexible, por ejemplo, CMD ["python", "text_preprocess.py", "input.csv", "output.csv"].
- Si el contenedor falla, revisa los logs con docker logs para depurar errores de codigo o dependencias.
Evalua tu comprension
Completa el quiz interactivo de arriba para ganar XP.