MÓDULO 14 · TRACKING CON MLFLOW · 30 MIN

Autolog y el árbol de ejecuciones

autolog() te quita de encima el registro de lo estándar —los hiperparámetros que la librería ya conoce y las métricas que calcula ella misma— y no toca nada más. Los nested runs le dan forma a lo que eso produce en masa, y search_runs convierte el conjunto en algo consultable. Los tres atacan el mismo problema a tres escalas: escribir menos, ordenar lo escrito, y volver a encontrarlo.
01 — El enganche
Qué captura autolog y qué te sigue tocando a ti
Lo capturaNo lo captura
Los hiperparámetros del estimadorCualquier métrica que calcules tú aparte
Las métricas que la librería produce al entrenarTus métricas de negocio
El modelo serializado como artefactoFicheros que generes por tu cuenta
Las versiones de librerías del entornoLo que ocurra fuera de la llamada a fit()
mlflow.sklearn.autolog()   # antes de entrenar, siempre

La regla de orden no admite matices: si llamas a autolog() después de fit(), no registra nada. Se engancha a la función de entrenamiento antes de que se ejecute; si ya se ejecutó, no queda nada a lo que engancharse. Y no lanza excepción: simplemente no aparecen datos.

De ahí el reparto real: autolog cubre el entrenamiento, y todo lo que evalúes después sobre el conjunto de test sigue siendo trabajo tuyo con log_metric. Los dos conviven dentro del mismo run sin estorbarse.

02 — La forma
Dieciocho filas planas no se leen
run · n=50 d=5— ¿de qué barrido era?
run · n=50 d=10— ¿y el de ayer?
run · n=100 d=5— ¿cuál fue el mejor?
… ×15 más— sin jerarquía, todo pesa igual
barrido · 18 combinaciones · ganador: n=200 d=10
n=50 d=5f1 por combinación
n=50 d=10f1 por combinación
… los demás, plegadosse abren si hacen falta
with mlflow.start_run(run_name="barrido") as padre:
    for params in combinaciones:
        with mlflow.start_run(nested=True):
            ...

nested=True no cambia lo que se registra: cambia quién es el padre. Y el padre se gana el sitio por lo que puedes escribir en él y en ningún hijo: el total de combinaciones, el espacio de búsqueda, el ganador. El hijo responde «qué pasó con estos parámetros»; el padre responde «qué pasó con esta búsqueda».

// sin padre, la única forma de agrupar es la hora de inicio — y eso se rompe en cuanto dos barridos se solapan
03 — La consulta
Cuando el tracking deja de mirarse y empieza a preguntarse
mlflow.search_runs(
    experiment_names=["mi_experimento"],
    filter_string="metrics.f1 > 0.85",
    order_by=["metrics.f1 DESC"],
)

Devuelve un DataFrame, y ahí está el salto de nivel: dejas de mirar la interfaz y empiezas a decidir con código — «coge el mejor de esta semana y regístralo». Tres detalles que ahorran una tarde entera:

DetalleQué pasa si lo ignoras
Las columnas llevan prefijo: metrics., params., tags.El filtro no encuentra nada y parece que no hay runs
Los parámetros son cadenas de textoparams.n_estimators > "50" compara alfabéticamente: "100" es menor que "50"
runs.columns da los nombres exactosPersigues un KeyError por un nombre que recordabas mal

El segundo es el que muerde de verdad, porque no falla: devuelve resultados, y los devuelve mal. Si vas a comparar por magnitud, el número tiene que estar registrado también como métrica.

Auditoría

El material dice que, tras el barrido, verás «las curvas de entrenamiento, gracias a autolog». Para un estimador de scikit-learn, autolog registra las métricas de entrenamiento del fit — un puñado de valores, no una curva de aprendizaje por época. ¿Ves tú una curva en la pestaña Metrics de un RandomForestClassifier, o cuatro números sueltos?

Y hay una contradicción interna que vale la pena mirar de frente: la guía celebra que autolog «registra todo automáticamente», mientras el ejercicio del mismo módulo te instruye literalmente a «registrar las métricas de test manualmente, porque el autolog solo captura las de entrenamiento». Las dos frases no pueden ser ciertas a la vez. ¿Cuál de las dos describe lo que ves en tu instalación, y qué te dice eso sobre cuánto fiarte del resto de afirmaciones automáticas de esta unidad?

Para hacer
Provoca el fallo silencioso a propósito

Coge un entrenamiento cualquiera y llama a mlflow.sklearn.autolog() después de fit(). Ejecútalo. No falla, no avisa, y el run aparece en la UI sin parámetros ni métricas.

Ahora apunta cuánto habrías tardado en darte cuenta si ese fuese el run número 40 de un barrido nocturno. Ese número es el coste real de un fallo que no grita — y la razón por la que la primera línea de un script de entrenamiento es la llamada a autolog.