Начало работы. Создание первой модели машинного обучения в Databricks

В этом примере записной книжки показано, как обучить модель классификации машинного обучения в Databricks. Databricks Runtime для Машинное обучение поставляется с множеством предварительно установленных библиотек, включая scikit-learn для обучения и предварительной обработки алгоритмов, MLflow для отслеживания процесса разработки моделей и Optuna для масштабирования настройки гиперпараметра.

В этой записной книжке вы создаете модель классификации для прогнозирования того, считается ли вино "высоким качеством". Набор данных состоит из 11 признаков различных вин (например, содержание алкоголя, кислотность и остаточный сахар) и рейтинг качества от 1 до 10.

Темы, рассматриваемые в этом руководстве:

  • Часть 1. Обучение модели классификации с помощью отслеживания MLflow
  • Часть 2. Настройка гиперпараметра для повышения производительности модели
  • Часть 3. Сохранение результатов и моделей в каталоге Unity
  • Часть 4. Развертывание модели

Дополнительные сведения об внедрении машинного обучения в Databricks, включая управление жизненным циклом модели и инференцию модели, см. в разделе "Пример полного цикла машинного обучения".

Набор данных доступен из репозитория UCI Машинное обучение и представлен в Modeling винных предпочтений по интеллектуальному анализу данных из физических химических свойств [Cortez et al., 2009].

Требования

Setup

В этом разделе вы должны сделать следующее:

  • Настройте клиент MLflow для использования каталога Unity в качестве реестра моделей.
  • Задайте каталог и схему, в которой будет зарегистрирована модель.
  • Считывать данные и сохранять их в таблицах каталога Unity.
  • Предварительная обработка данных.

Настройка клиента MLflow

По умолчанию клиент MLflow Python создает модели в реестре моделей рабочих областей Databricks. Чтобы сохранить модели в каталоге Unity, настройте клиент MLflow, как показано в следующей ячейке.

import mlflow
mlflow.set_registry_uri("databricks-uc")

Следующая ячейка задает каталог и схему, в которой будет зарегистрирована модель. Необходимо иметь USE CATALOG привилегии в каталоге, а также привилегии USE_SCHEMA, CREATE_TABLE и CREATE_MODEL в схеме. При необходимости измените имена каталога и схем в следующей ячейке.

Дополнительные сведения см. в документации по каталогу Unity.

# Specify the catalog and schema to use. You must have USE_CATALOG privilege on the catalog and USE_SCHEMA, CREATE_TABLE, and CREATE_MODEL privileges on the schema.
# Change the catalog and schema here if necessary.
CATALOG_NAME = "main"
SCHEMA_NAME = "default"

Загрузка данных и сохранение их в таблицах каталога Unity

Набор данных доступен в databricks-datasets. В следующей ячейке вы загружаете данные из файлов .csv в Spark DataFrames. Затем вы записываете DataFrame в таблицы в каталоге Unity. Это сохраняет данные и позволяет управлять тем, как поделиться данными с другими пользователями.

white_wine = spark.read.csv("/databricks-datasets/wine-quality/winequality-white.csv", sep=';', header=True)
red_wine = spark.read.csv("/databricks-datasets/wine-quality/winequality-red.csv", sep=';', header=True)

# Remove the spaces from the column names
for c in white_wine.columns:
    white_wine = white_wine.withColumnRenamed(c, c.replace(" ", "_"))
for c in red_wine.columns:
    red_wine = red_wine.withColumnRenamed(c, c.replace(" ", "_"))

# Define table names
red_wine_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine"
white_wine_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine"

# Write to tables in Unity Catalog
spark.sql(f"DROP TABLE IF EXISTS {red_wine_table}")
spark.sql(f"DROP TABLE IF EXISTS {white_wine_table}")
white_wine.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine")
red_wine.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine")

Предварительная обработка данных

# Import required libraries
import numpy as np
import pandas as pd
import sklearn.datasets
import sklearn.metrics
import sklearn.model_selection
import sklearn.ensemble

import matplotlib.pyplot as plt

import optuna
from mlflow.optuna.storage import MlflowStorage
from mlflow.pyspark.optuna.study import MlflowSparkStudy
# Load data from Unity Catalog as Pandas dataframes
white_wine = spark.read.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.white_wine").toPandas()
red_wine = spark.read.table(f"{CATALOG_NAME}.{SCHEMA_NAME}.red_wine").toPandas()

# Add Boolean fields for red and white wine
white_wine['is_red'] = 0.0
red_wine['is_red'] = 1.0
data_df = pd.concat([white_wine, red_wine], axis=0)

# Define classification labels based on the wine quality
data_labels = data_df['quality'].astype('int') >= 7
data_df = data_df.drop(['quality'], axis=1)

# Split 80/20 train-test
X_train, X_test, y_train, y_test = sklearn.model_selection.train_test_split(
  data_df,
  data_labels,
  test_size=0.2,
  random_state=1
)

Часть 1. Обучение модели классификации

# Enable MLflow autologging for this notebook
mlflow.autolog()

Затем следует обучить классификатор в контексте запуска MLflow, который автоматически логирует обученную модель и множество связанных метрик и параметров.

Вы можете дополнить логирование дополнительными метриками, такими как оценка AUC модели в тестовом наборе данных.

with mlflow.start_run(run_name='gradient_boost') as run:
    model = sklearn.ensemble.GradientBoostingClassifier(random_state=0)

    # Models, parameters, and training metrics are tracked automatically
    model.fit(X_train, y_train)

    predicted_probs = model.predict_proba(X_test)
    roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
    roc_curve = sklearn.metrics.RocCurveDisplay.from_estimator(model, X_test, y_test)

    # Save the ROC curve plot to a file
    roc_curve.figure_.savefig("roc_curve.png")

    # The AUC score on test data is not automatically logged, so log it manually
    mlflow.log_metric("test_auc", roc_auc)

    # Log the ROC curve image file as an artifact
    mlflow.log_artifact("roc_curve.png")

    print("Test AUC of: {}".format(roc_auc))

Просмотр запусков MLflow

Чтобы просмотреть зарегистрированный учебный запуск, щелкните " в правом верхнем углу записной книжки, чтобы отобразить боковую панель эксперимента.Experiment icon При необходимости щелкните значок обновления, чтобы получить и отслеживать последние запуски.

Эксперименты, перечисленные в правой боковой панели

Чтобы отобразить более подробную страницу эксперимента MLflow, щелкните значок страницы эксперимента. Эта страница позволяет сравнивать запуски и просматривать сведения о конкретных запусках. См. раздел "Отслеживание разработки моделей с помощью MLflow".

Загрузка моделей

Вы также можете получить доступ к результатам для определенного запуска с помощью API MLflow. Код в следующей ячейке показывает, как загрузить модель, обученную в заданном запуске MLflow, и использовать ее для прогнозирования. Вы также можете найти фрагменты кода для загрузки определенных моделей на странице запуска MLflow.

# After a model has been logged, you can load it in different notebooks or jobs
# mlflow.pyfunc.load_model makes model prediction available under a common API
model_loaded = mlflow.pyfunc.load_model(
  'runs:/{run_id}/model'.format(
    run_id=run.info.run_id
  )
)

predictions_loaded = model_loaded.predict(X_test)
predictions_original = model.predict(X_test)

# The loaded model should match the original
assert(np.array_equal(predictions_loaded, predictions_original))

Part 2 (Развертывание виртуальных машин в облаке, часть 2). Настройка гиперпараметров

На этом этапе вы обучили простую модель и использовали службу отслеживания MLflow для организации работы. Затем можно выполнить более сложную настройку с помощью Optuna.

Параллельное обучение с помощью Optuna

Optuna — это библиотека Python с открытым кодом для настройки гиперпараметра, масштабируемая по горизонтали в нескольких вычислительных ресурсах. Дополнительные сведения об использовании Optuna в Databricks см. в разделе о настройке Гиперпараметра с помощью Optuna.

def objective(trial):
  # Enable autologging on each worker
  mlflow.autolog()
  with mlflow.start_run(nested=True):
    params = {
      'n_estimators': trial.suggest_int('n_estimators', 20, 1000),
      'learning_rate': trial.suggest_float('learning_rate', 0.05, 1.0, log=True),
      'max_depth': trial.suggest_int('max_depth', 2, 5),
    }
    model_hp = sklearn.ensemble.GradientBoostingClassifier(
      random_state=0,
      **params
    )
    model_hp.fit(X_train, y_train)
    predicted_probs = model_hp.predict_proba(X_test)
    # Tune based on the test AUC
    # In production, you could use a separate validation set instead
    roc_auc = sklearn.metrics.roc_auc_score(y_test, predicted_probs[:,1])
    mlflow.log_metric('test_auc', roc_auc)

    # Negate the AUC because Optuna minimizes the objective by default
    return -roc_auc


with mlflow.start_run(run_name='gb_optuna') as run:
  # Use the MLflow Tracking Server as the Optuna storage backend
  experiment_id = mlflow.active_run().info.experiment_id
  mlflow_storage = MlflowStorage(experiment_id=experiment_id)

  # MlflowSparkStudy distributes the tuning using Spark workers
  mlflow_study = MlflowSparkStudy(
    study_name="gb-optuna-tuning",
    storage=mlflow_storage,
  )

  mlflow_study.optimize(objective, n_trials=32, n_jobs=4)

Поиск выполняется для получения оптимальной модели

Так как все запуски отслеживаются MLflow, вы можете получить метрики и параметры для лучшего запуска, используя API поиска MLflow, чтобы найти настройку запуска с самым высоким значением AUC теста.

Эта настроенная модель должна работать лучше, чем более простые модели, обученные в части 1.

# Sort runs by their test auc. In case of ties, use the most recent run.
best_run = mlflow.search_runs(
  order_by=['metrics.test_auc DESC', 'start_time DESC'],
  max_results=10,
).iloc[0]
print('Best Run')
print('AUC: {}'.format(best_run["metrics.test_auc"]))
print('Num Estimators: {}'.format(best_run["params.n_estimators"]))
print('Max Depth: {}'.format(best_run["params.max_depth"]))
print('Learning Rate: {}'.format(best_run["params.learning_rate"]))

best_model_pyfunc = mlflow.pyfunc.load_model(
  'runs:/{run_id}/model'.format(
    run_id=best_run.run_id
  )
)

# Make a dataset with all predictions
best_model_predictions = X_test
best_model_predictions["prediction"] = best_model_pyfunc.predict(X_test)

Часть 3. Сохранение результатов и моделей в каталоге Unity

predictions_table = f"{CATALOG_NAME}.{SCHEMA_NAME}.predictions"
spark.sql(f"DROP TABLE IF EXISTS {predictions_table}")

results = spark.createDataFrame(best_model_predictions)

# Write results back to Unity Catalog from Python
results.write.saveAsTable(f"{CATALOG_NAME}.{SCHEMA_NAME}.predictions")
model_uri = 'runs:/{run_id}/model'.format(
    run_id=best_run.run_id
  )

mlflow.register_model(model_uri, f"{CATALOG_NAME}.{SCHEMA_NAME}.wine_quality_model")

Часть 4. Развертывание модели

После сохранения модели в каталоге Unity его можно развернуть с помощью пользовательского интерфейса обслуживания. Следующие инструкции содержат краткое описание. Дополнительные сведения см. в статье "Создание пользовательских конечных точек обслуживания моделей".

  1. Нажмите Сервис на боковой панели, чтобы отобразить интерфейс сервиса.

Пользовательский интерфейс обслуживания модели

  1. Нажмите кнопку "Создать конечную точку обслуживания".

  2. В поле "Имя" укажите имя конечной точки.

  3. В разделе "Обслуживаемые сущности"

    1. Щелкните в поле сущности , чтобы открыть форму выбора обслуживаемой сущности .
    2. Выберите "Мои модели— каталог Unity". Форма обновляется динамически в зависимости от вашего выбора.
    3. Выберите wine_quality_model и версию модели, которую хотите обслуживать.
    4. Выберите 100 в качестве процента трафика, который вы хотите направить в обслуживаемую модель.
    5. Выберите ЦП в качестве типа вычислений для этого примера.
    6. В разделе "Горизонтальное масштабирование вычислений" выберите Small в качестве размера горизонтального масштабирования вычислений.
  4. Нажмите кнопку Создать. Откроется страница "Обслуживание конечных точек " с состоянием конечной точки обслуживания , отображаемой как "Не готово".

  5. Когда конечная точка готова, выберите "Использовать " для отправки запроса вывода в конечную точку.

Пример записной книжки

Начало работы. Создание первой модели машинного обучения в Databricks

Получить блокнот