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.
| Lo captura | No lo captura |
|---|---|
| Los hiperparámetros del estimador | Cualquier métrica que calcules tú aparte |
| Las métricas que la librería produce al entrenar | Tus métricas de negocio |
| El modelo serializado como artefacto | Ficheros que generes por tu cuenta |
| Las versiones de librerías del entorno | Lo 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.
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».
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:
| Detalle | Qué 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 texto | params.n_estimators > "50" compara alfabéticamente: "100" es menor que "50" |
runs.columns da los nombres exactos | Persigues 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.
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?
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.