Seamos honestos: todos hemos pasado por eso.
Es viernes por la tarde. Ha entrenado un modelo, lo ha validado y ha implementado el canal de inferencia. Las métricas se ven verdes. Cierras tu computadora portátil durante el fin de semana y disfrutas del descanso.
El lunes por la mañana, recibirá el mensaje “Error en la tubería” cuando se registre en el trabajo. ¿Qué está sucediendo? Todo fue perfecto cuando implementaste el canal de inferencia.
La verdad es que el problema podría ser varias cosas. Quizás el equipo de ingeniería ascendente cambió la columna user_id de un número entero a una cadena. O tal vez la columna de precios de repente contenga números negativos. O mi favorito personal: el nombre de la columna cambió de creado_at a creado en (¡camelCase vuelve a atacar!).
La industria llama a esto Schema Drift. Yo lo llamo dolor de cabeza.
Últimamente se habla mucho de Contratos de Datos. Por lo general, esto implica venderle una costosa plataforma SaaS o una arquitectura de microservicios compleja. Pero si usted es solo un científico o ingeniero de datos que intenta evitar que sus canales de Python exploten, no necesariamente necesita una gran expansión empresarial.
La herramienta: Pandera
Veamos cómo crear un contrato de datos simple en Python usando la biblioteca Pandera. Es una biblioteca Python de código abierto que le permite definir esquemas como objetos de clase. Se siente muy similar a Pydantic (si ha usado FastAPI), pero está creado específicamente para DataFrames.
Para comenzar, simplemente puedes instalar pandera usando pip:
instalar pip pandera
Un ejemplo de la vida real: el feed de clientes potenciales de marketing
Veamos un escenario clásico. Está ingiriendo un archivo CSV de clientes potenciales de marketing de un proveedor externo.
Así es como esperamos que se vean los datos:
id: un número entero (debe ser único). correo electrónico: una cadena (en realidad debe parecerse a un correo electrónico). signup_date: un objeto de fecha y hora válido. lead_score: un valor flotante entre 0,0 y 1,0.
Aquí está la confusa realidad de nuestros datos sin procesar que recibimos:
import pandas as pd import numpy as np # Simulando datos entrantes que PODRÍAN romper nuestros datos de canalización = { “id”: [101, 102, 103, 104]”correo electrónico”: [“[email protected]”, “[email protected]”, “INVALID_EMAIL”, “[email protected]”]”fecha_inscripción”: [“2024-01-01”, “2024-01-02”, “2024-01-03”, “2024-01-04″]”puntuación_lead”: [0.5, 0.8, 1.5, -0.1] # Nota: ¡1,5 y -0,1 están fuera de límites! } df = pd.DataFrame(datos)
Si introdujera este marco de datos en un modelo esperando una puntuación entre 0 y 1, sus predicciones serían basura. Si intentara unirse con una identificación y hubiera duplicados, el recuento de filas se dispararía. ¡Los datos desordenados conducen a una ciencia de datos desordenada!
Paso 1: definir el contrato
En lugar de escribir una docena de declaraciones if para verificar la calidad de los datos, definimos un SchemaModel. Este es nuestro contrato.
importar pandera como pa desde pandera.typing importar clase de serie LeadsContract(pa.SchemaModel): # 1. Verifique los tipos de datos y la identificación de existencia: Serie[int] = pa.Field(unique=True, ge=0) # 2. Verifique el formato usando el correo electrónico regex: Serie[str] = pa.Campo(str_matches=r”[^@]+@[^@]+\.[^@]+”) # 3. Coaccionar tipos (convertir fechas de cadena en objetos de fecha y hora automáticamente) signup_date: Serie[pd.Timestamp] = pa.Field(coerce=True) # 4. Verificar la lógica empresarial (límites) lead_score: Serie[float] = pa.Field(ge=0.0, le=1.0) class Config: # Esto garantiza el rigor: si aparece una columna adicional o falta una, arroja un error. estricto = verdadero
Revise el código anterior para tener una idea general de cómo Pandera establece un contrato. Puede preocuparse por los detalles más adelante cuando consulte la documentación de Pandera.
Paso 2: hacer cumplir el contrato
Ahora, necesitamos aplicar el contrato que hicimos a nuestros datos. La forma ingenua de hacer esto es ejecutar LeadsContract.validate(df). Esto funciona, pero falla con el primer error que encuentra. En producción, normalmente desea saber todo lo que está mal en el archivo, no solo la primera fila.
Podemos habilitar la validación “diez” para detectar todos los errores a la vez.
intente: # lazy=True significa “encontrar todos los errores antes de fallar” valided_df = LeadsContract.validate(df, lazy=True) print(“¡Los datos pasaron la validación! Procediendo a ETL…”) excepto pa.errors.SchemaErrors como err: print(“⚠️ ¡Contrato de datos incumplido!”) print(f”Total de errores encontrados: {len(err.failure_cases)}”) # Veamos las fallas específicas print(“\nFailure Report:”) print(err.failure_cases[[‘column’, ‘check’, ‘failure_case’]])
La salida
Si ejecuta el código anterior, no obtendrá un KeyError genérico. Recibirá un informe específico que detalla exactamente por qué se incumplió el contrato:
⚠️ ¡Contrato de datos incumplido! Total de errores encontrados: 3 Informe de fallas: verificación de columna caso_fallo 0 correo electrónico str_matches INVALID_EMAIL 1 puntaje_de_plomo menor_que_o_igual_a 1,5 2 puntaje_de_plomo mayor_que_o_igual_a -0,1
En un escenario más realista, probablemente registraría la salida en un archivo y configuraría alertas para recibir una notificación si algo no funciona.
Por qué esto importa
Este enfoque cambia la dinámica de su trabajo.
Sin un contrato, su código falla en lo profundo de la lógica de transformación (o peor aún, no falla y escribe datos incorrectos en el almacén). Pasas horas depurando valores de NaN.
Con contrato:
Falla rápido: el oleoducto se detiene en la puerta. Los datos incorrectos nunca entran en su lógica central. Eliminar la culpa: puede enviar ese informe de error al proveedor de datos y decir: “Las filas 3 y 4 violaron el esquema. Por favor corríjalo”. Documentación: la clase LeadsContract sirve como documentación viva. Los nuevos miembros del proyecto no necesitan adivinar qué representan las columnas; simplemente pueden leer el código. También evita establecer un contrato de datos independiente en SharePoint, Confluence o cualquier otro lugar que quede obsoleto rápidamente.
La solución “suficientemente buena”
Definitivamente puedes profundizar más. Puede integrar esto con Airflow, enviar métricas a un panel o usar herramientas como great_expectations para crear perfiles estadísticos más complejos.
Pero para el 90% de los casos de uso que veo, un simple paso de validación al inicio de su script de Python es suficiente para dormir profundamente un viernes por la noche.
Empiece poco a poco. Defina un esquema para su conjunto de datos más desordenado, envuélvalo en un bloque try/catch y vea cuántos dolores de cabeza le ahorra esta semana. Cuando este enfoque simple ya no sea adecuado, ENTONCES consideraría herramientas más elaboradas para los contactos de datos.
Si está interesado en IA, ciencia de datos o ingeniería de datos, sígueme o conéctate en LinkedIn.