Una guía de codificación para implementar la optimización avanzada de hiperparámetros con Optuna mediante la poda de búsqueda multiobjetivo, la parada temprana y el análisis visual profundo

En este tutorial, implementamos un flujo de trabajo avanzado de Optuna que explora sistemáticamente la poda, la optimización multiobjetivo, las devoluciones de llamada personalizadas y la visualización enriquecida. A través de cada fragmento, vemos cómo Optuna nos ayuda a dar forma a espacios de búsqueda más inteligentes, acelerar los experimentos y extraer información que oriente la mejora del modelo. Trabajamos con conjuntos de datos reales, diseñamos estrategias de búsqueda eficientes y analizamos el comportamiento de las pruebas de una manera que resulta interactiva, rápida e intuitiva. Consulta los CÓDIGOS COMPLETOS aquí.

importar optuna desde optuna.pruners importar MedianPruner desde optuna.samplers importar TPESampler importar numpy como np desde sklearn.datasets importar load_breast_cancer, load_diabetes desde sklearn.model_selection importar cross_val_score, KFold desde sklearn.ensemble importar RandomForestClassifier, GradientBoostingClassifier importar matplotlib.pyplot as plt def Objective_with_pruning(trial): X, y = load_breast_cancer(return_X_y=True) params = { ‘n_estimators’: juicio.suggest_int(‘n_estimators’, 50, 200), ‘min_samples_split’: juicio.suggest_int(‘min_samples_split’, 2, 20), ‘min_samples_leaf’: juicio.suggest_int(‘min_samples_leaf’, 1, 10), ‘submuestra’: juicio.suggest_float(‘submuestra’, 0.6, 1.0), ‘max_features’: juicio.suggest_categorical(‘max_features’, [‘sqrt’, ‘log2′, None]), } modelo = GradientBoostingClassifier(**params, random_state=42) kf = KFold(n_splits=3, shuffle=True, random_state=42) puntuaciones = []
para plegar, (train_idx, val_idx) en enumerar (kf.split(X)): X_train, X_val = X[train_idx]X[val_idx]
y_tren, y_val = y[train_idx]y[val_idx]
model.fit(X_train, y_train) puntuación = model.score(X_val, y_val) puntuaciones.append(puntuación) juicio.report(np.mean(puntuaciones), fold) si prueba.should_prune(): aumentar optuna.TrialPruned() devolver np.mean(puntuaciones) estudio1 = optuna.create_study( dirección=’maximizar’, muestreador=TPESampler(semilla=42), podadora=MedianPruner(n_startup_trials=5, n_warmup_steps=1) ) estudio1.optimize(objetivo_con_poda, n_pruebas=30, show_progress_bar=True) print(estudio1.mejor_valor, estudio1.mejores_params)

Configuramos todas las importaciones principales y definimos nuestra primera función objetivo con la poda. A medida que ejecutamos la optimización de aumento de gradiente, observamos a Optuna podando activamente las pruebas más débiles y guiándonos hacia regiones de hiperparámetros más fuertes. Sentimos que la optimización se vuelve más rápida e inteligente a medida que avanza el estudio. Consulta los CÓDIGOS COMPLETOS aquí.

def multi_objetivo(prueba): X, y = load_breast_cancer(return_X_y=True) n_estimadores = juicio.suggest_int(‘n_estimadores’, 10, 200) profundidad_max = prueba.suggest_int(‘profundidad_max’, 2, 20) min_samples_split = trial.suggest_int(‘min_samples_split’, 2, 20) modelo = RandomForestClassifier( n_estimators=n_estimators, max_profundidad=max_profundidad, min_samples_split=min_samples_split, random_state=42, n_jobs=-1 ) precisión = cross_val_score(modelo, X, y, cv=3, puntuación = ‘precisión’, n_trabajos = -1). media () complejidad = n_estimadores * precisión de retorno de profundidad máxima, estudio de complejidad2 = optuna.create_study (direcciones =[‘maximize’, ‘minimize’]sampler=TPESampler(seed=42) ) Study2.optimize(multi_objective, n_trials=50, show_progress_bar=True) para t en Study2.best_trials[:3]: imprimir(t.número, t.valores)

Pasamos a una configuración de objetivos múltiples donde optimizamos tanto la precisión como la complejidad del modelo. A medida que exploramos diferentes configuraciones, vemos cómo Optuna construye automáticamente un frente de Pareto, lo que nos permite comparar compensaciones en lugar de perseguir una puntuación única. Esto nos proporciona una comprensión más profunda de cómo interactúan entre sí las métricas en competencia. Consulta los CÓDIGOS COMPLETOS aquí.

clase EarlyStoppingCallback: def __init__(self, early_stopping_rounds=10, dirección=’maximize’): self.early_stopping_rounds = early_stopping_rounds self.direction = dirección self.best_value = float(‘-inf’) if dirección == ‘maximizar’ else float(‘inf’) self.counter = 0 def __call__(self, estudio, prueba): if juicio.estado != optuna.trial.TrialState.COMPLETE: return v = juicio.valor si self.direction == ‘maximizar’: if v > self.best_value: self.best_value, self.counter = v, 0 else: self.counter += 1 else: if v < self.best_value: self.best_value, self.counter = v, 0 else: self.counter += 1 if self.counter >= self.early_stopping_rounds: Study.stop() def Objective_regression(prueba): X, y = load_diabetes(return_X_y=True) alpha = juicio.suggest_float(‘alpha’, 1e-3, 10.0, log=True) max_iter = juicio.suggest_int(‘max_iter’, 100, 2000) de sklearn.linear_model import Ridge model = Ridge(alpha=alpha, max_iter=max_iter, random_state=42) puntuación = cross_val_score(model, X, y, cv=5, scoring=’neg_mean_squared_error’, n_jobs=-1).mean() return -score early_stopping = EarlyStoppingCallback(early_stopping_rounds=15, dirección=’minimizar’) estudio3 = optuna.create_study(dirección=’minimizar’, muestreador=TPESampler(seed=42)) estudio3.optimize(regresión_objetiva, n_trials=100, devoluciones de llamada=[early_stopping]show_progress_bar=True) print(estudio3.mejor_valor, estudio3.mejores_params)

Introducimos nuestra propia devolución de llamada de parada temprana y la conectamos a un objetivo de regresión. Observamos cómo el estudio se detiene cuando el progreso se detiene, ahorrando tiempo y cálculo. Esto nos hace sentir el poder de personalizar el flujo de Optuna para que coincida con el comportamiento de entrenamiento del mundo real. Consulta los CÓDIGOS COMPLETOS aquí.

higo, ejes = plt.subplots(2, 2, tamaño de higo=(14, 10)) eje = ejes[0, 0]
valores = [t.value for t in study1.trials if t.value is not None]
ax.plot(valores, marcador=”o”, marcadorsize=3) ax.axhline(y=study1.best_value, color=”r”, linestyle=”–“) ax.set_title(‘Historia del estudio 1’) ax = ejes[0, 1]
importancia = optuna.importance.get_param_importances(estudio1) params = lista(importancia.keys())[:5]
valores = [importance[p] para p en parámetros]ax.barh(params, vals) ax.set_title(‘Importancia del parámetro’) ax = ejes[1, 0]
para t en estudio2.ensayos: si t.valores: ax.scatter(t.valores[0]valores t.[1]alfa=0,3) para t en estudio2.best_trials: ax.scatter(t.values[0]valores t.[1]c=”rojo”, s=90) ax.set_title(‘Frente de Pareto’) ax = ejes[1, 1]
pares = [(t.params.get(‘max_depth’, 0), t.value) for t in study1.trials if t.value]
Xv, Yv = zip(*pares) si los pares else ([], []) ax.scatter(Xv, Yv, alpha=0.6) ax.set_title(‘máxima profundidad vs precisión’) plt.tight_layout() plt.savefig(‘optuna_analysis.png’, dpi=150) plt.show()

Visualizamos todo lo que hemos ejecutado hasta ahora. Generamos curvas de optimización, importancias de parámetros, frentes de Pareto y relaciones parámetro-métricas, que nos ayudan a interpretar todo el experimento de un vistazo. A medida que examinamos los gráficos, obtenemos información sobre dónde funciona mejor el modelo y por qué. Consulta los CÓDIGOS COMPLETOS aquí.

p1 = largo([t for t in study1.trials if t.state == optuna.trial.TrialState.PRUNED]) print(“Estudio 1 Mejor precisión:”, estudio1.best_value) print(“Estudio 1 % podado:”, p1 / len(study1.trials) * 100) print(“Estudio 2 Soluciones de Pareto:”, len(study2.best_trials)) print(“Estudio 3 Mejor MSE:”, estudio3.best_value) print(“Estudio 3 Ensayos:”, len(estudio3.ensayos))

Resumimos los resultados clave de los tres estudios, revisando la precisión, la eficiencia de la poda, las soluciones de Pareto y el MSE de regresión. Ver todo condensado en unas pocas líneas nos da una idea clara de nuestro viaje de optimización. Ahora nos sentimos seguros de poder ampliar y adaptar esta configuración para experimentos más avanzados.

En conclusión, hemos comprendido cómo construir potentes canales de optimización de hiperparámetros que van mucho más allá del simple ajuste de una sola métrica. Combinamos herramientas de poda, optimización de Pareto, parada anticipada y análisis para formar un flujo de trabajo completo y flexible. Ahora nos sentimos seguros de poder adaptar esta plantilla para cualquier modelo futuro de ML o DL que queramos optimizar, sabiendo que ahora tenemos un modelo claro y práctico para la experimentación de alta calidad basada en Optuna.

Consulta los CÓDIGOS COMPLETOS aquí. No dude en consultar nuestra página de GitHub para tutoriales, códigos y cuadernos. Además, no dude en seguirnos en Twitter y no olvide unirse a nuestro SubReddit de más de 100.000 ML y suscribirse a nuestro boletín. ¡Esperar! estas en telegrama? Ahora también puedes unirte a nosotros en Telegram.

Asif Razzaq es el director ejecutivo de Marktechpost Media Inc.. Como empresario e ingeniero visionario, Asif está comprometido a aprovechar el potencial de la inteligencia artificial para el bien social. Su esfuerzo más reciente es el lanzamiento de una plataforma de medios de inteligencia artificial, Marktechpost, que se destaca por su cobertura en profundidad del aprendizaje automático y las noticias sobre aprendizaje profundo que es técnicamente sólida y fácilmente comprensible para una amplia audiencia. La plataforma cuenta con más de 2 millones de visitas mensuales, lo que ilustra su popularidad entre el público.

🙌 Siga MARKTECHPOST: agréguenos como fuente preferida en Google.