Advertisement
alien_555

mlflow

Apr 16th, 2025 (edited)
302
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.99 KB | None | 0 0
  1. RUN_NAME = "model_bayesian_search"
  2. STUDY_DB_NAME = "sqlite:///local.study.db"
  3. STUDY_NAME = "churn_model"
  4.  
  5.  
  6. experiment = mlflow.get_experiment_by_name(EXPERIMENT_NAME)
  7. if not experiment:
  8.     experiment_id = mlflow.create_experiment(EXPERIMENT_NAME)
  9. else:
  10.     experiment_id = experiment.experiment_id
  11.    
  12. if mlflow.active_run() is not None:
  13.     mlflow.end_run()
  14.  
  15.  
  16. def objective(trial: optuna.Trial) -> float:
  17.     print("Optimizing...")
  18.     # Вложенные запуски
  19.     # with mlflow.start_run(run_id=run_id, nested=True) as nested_run:
  20.     print("Start nested_run")
  21.    
  22.     param = {
  23.         "learning_rate": trial.suggest_float("learning_rate", 0.001, 0.1, log=True),
  24.         "depth": trial.suggest_int("depth", 1, 12),
  25.         "l2_leaf_reg": trial.suggest_float("l2_leaf_reg", 0.1, 5),
  26.         "random_strength": trial.suggest_float("random_strength", 0.1, 5),
  27.         "loss_function": "Logloss",
  28.         "task_type": "CPU",
  29.         "random_seed": 0,
  30.         "iterations": 300,
  31.         "verbose": False,
  32.         "auto_class_weights": 'Balanced',
  33.         "cat_features": cat_cols,
  34.     }
  35.  
  36.     model = CatBoostClassifier(**param)
  37.  
  38.     skf = StratifiedKFold(n_splits=2,
  39.                         shuffle=True,
  40.                         random_state=555)
  41.  
  42.     metrics = defaultdict(list)
  43.     #  train_index и val_index — это массивы индексов, которые указывают, какие строки из исходного DataFrame X_train (или y_train) должны быть включены в обучающую и валидационную выборки для каждого фолда i, соответственно.
  44.     for i, (train_index, val_index) in enumerate(skf.split(X_train, y_train)):
  45.         # Разделяем данные на обучающую и валидационную выборки
  46.         train_x, val_x = X_train.iloc[train_index], X_train.iloc[val_index]
  47.         train_y, val_y = y_train.iloc[train_index], y_train.iloc[val_index]
  48.        
  49.         # Обучаем модель на обучающей выборке
  50.         model.fit(train_x, train_y, verbose=False) #verbose=False для уменьшения вывода
  51.  
  52.         # Получаем предсказания и вероятности на валидационной выборке
  53.         prediction = model.predict(val_x)
  54.         probas = model.predict_proba(val_x)[:, 1]
  55.  
  56.         # Вычисление метрик
  57.         # Вычисление confusion matrix с нормализацией
  58.         cm = confusion_matrix(val_y, prediction, normalize='all')
  59.         # Извлечение значений из нормализованной матрицы
  60.         TN = cm[0, 0]  # True Negative
  61.         FP = cm[0, 1]  # False Positive (ошибка первого рода)
  62.         FN = cm[1, 0]  # False Negative (ошибка второго рода)
  63.         TP = cm[1, 1]  # True Positive
  64.         # err_1 — ошибка первого рода
  65.         # err_2 — ошибка второго рода
  66.         err_1 = FP  # False Positive Rate (доля от общего числа)
  67.         err_2 = FN  # False Negative Rate (доля от общего числа)
  68.        
  69.         auc = roc_auc_score(val_y, probas)
  70.         precision = precision_score(val_y, prediction)
  71.         recall = recall_score(val_y, prediction)
  72.         f1 = f1_score(val_y, prediction)
  73.         logloss = log_loss(val_y, probas)
  74.        
  75.         metrics["err1"].append(err_1)
  76.         metrics["err2"].append(err_2)
  77.         metrics["auc"].append(auc)
  78.         metrics["precision"].append(precision)
  79.         metrics["recall"].append(recall)
  80.         metrics["f1"].append(f1)
  81.         metrics["logloss"].append(logloss)
  82.  
  83.     err_1 = np.median(metrics['err1'])
  84.     err_2 = np.median(metrics['err2'])
  85.     auc = np.median(metrics['auc'])
  86.     precision = np.median(metrics["precision"])
  87.     recall = np.median(metrics["recall"])
  88.     f1 = np.median(metrics["f1"])
  89.     logloss = np.median(metrics["logloss"])
  90.    
  91.     mlflow.log_metric("err1", err_1)
  92.     mlflow.log_metric("err2", err_2)
  93.     mlflow.log_metric("auc", auc)
  94.     mlflow.log_metric("precision", precision)
  95.     mlflow.log_metric("recall", recall)
  96.     mlflow.log_metric("f1", f1)
  97.     mlflow.log_metric("logloss", logloss)
  98.    
  99.     # mlflow.end_run()
  100.  
  101.     return auc
  102.  
  103.  
  104. with mlflow.start_run(run_name=RUN_NAME, experiment_id=experiment_id) as run:
  105.     run_id = run.info.run_id
  106.  
  107.     # MLflow Callback
  108.     mlflc = MLflowCallback(
  109.         tracking_uri=f'http://{TRACKING_SERVER_HOST}:{TRACKING_SERVER_PORT}',
  110.         metric_name="AUC",
  111.         create_experiment=False, # не нужно создавать эксперимент каждый раз
  112.         mlflow_kwargs = {'experiment_id': experiment_id, 'tags': {"mlflow.parentRunId": run_id}}
  113.     )
  114.  
  115.     study = optuna.create_study(direction='maximize',
  116.                                 study_name=STUDY_NAME,
  117.                                 storage=STUDY_DB_NAME,
  118.                                 load_if_exists=True,
  119.                                 sampler=optuna.samplers.TPESampler())
  120.  
  121.     study.optimize(objective,
  122.                     n_trials=10,
  123.                     callbacks=[mlflc])
  124.     best_params = study.best_trial.params
  125.  
  126.  
  127.  
  128.     # Создаем модель с лучшими параметрами
  129.     best_model = CatBoostClassifier(**best_params,
  130.                                     auto_class_weights='Balanced',  
  131.                                     cat_features=cat_cols,
  132.                                     loss_function="Logloss", # нужно указать явно, т.к. его нет в best_params
  133.                                     task_type="CPU",
  134.                                     random_seed=555,
  135.                                     verbose=False)
  136.  
  137.     # Обучаем модель на ВСЕМ тренировочном наборе
  138.     best_model.fit(X_train, y_train)
  139.  
  140.     # Логируем модель в MLflow
  141.     # Код логирования модели находится вне цикла оптимизации и вызывается только один раз после того, как Optuna завершит поиск лучших гиперпараметров.
  142.     mlflow.catboost.log_model(
  143.         cb_model=best_model,
  144.         artifact_path="models", # директория для хранения модели
  145.         registered_model_name=REGISTRY_MODEL_NAME,
  146.         pip_requirements=pip_requirements,
  147.         signature=signature,
  148.         input_example=input_example,
  149.         await_registration_for=await_registration_for  
  150.         )
  151.     print("Best model logged to MLflow.")
  152.     # Получаем данные о запуске эксперимента по его уникальному идентификатору
  153.     run = mlflow.get_run(run_id)
  154.  
  155.  
  156.     print(f"Number of finished trials: {len(study.trials)}")
  157.     print(f"Best params: {best_params}")
  158.     print(f"Данные о запуске\n{run}")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement