Erste Schritte: Erstellen Ihres ersten Machine Learning-Modells auf Databricks

In diesem Beispielnotizbuch wird veranschaulicht, wie Sie ein Machine Learning-Klassifizierungsmodell auf Databricks trainieren. Databricks Runtime für Machine Learning enthält viele vorinstallierte Bibliotheken, einschließlich scikit-learn für Schulungen und Vorabverarbeitungsalgorithmen, MLflow zum Nachverfolgen des Modellentwicklungsprozesses und Optuna zum Skalieren der Hyperparameteroptimierung.

In diesem Notizbuch erstellen Sie ein Klassifizierungsmodell, um vorherzusagen, ob ein Wein als "qualitativ hochwertig" gilt. Das Dataset besteht aus 11 Features verschiedener Weine (zum Beispiel Alkoholgehalt, Säure und Restzucker) und einer Qualitätsbewertung zwischen 1 und 10.

In diesem Lernprogramm wird Folgendes behandelt:

  • Teil 1: Trainieren eines Klassifizierungsmodells mit MLflow-Nachverfolgung
  • Teil 2: Hyperparameteroptimierung zur Verbesserung der Modellleistung
  • Teil 3: Speichern von Ergebnissen und Modellen im Unity-Katalog
  • Teil 4: Bereitstellen des Modells

Weitere Informationen zum Einsatz von maschinellem Lernen in der Produktion auf Databricks, einschließlich Modelllebenszyklus-Management und Modellinferenz, finden Sie im ML End to End Example.

Das Dataset ist aus dem UCI Machine Learning Repository verfügbar und wird in Modeling weinpräferenzen durch Data Mining aus physikalischen chemischen Eigenschaften [Cortez et al., 2009] präsentiert.

Anforderungen

Konfiguration

In diesem Abschnitt gehen Sie wie folgt vor:

  • Konfigurieren Sie den MLflow-Client für die Verwendung des Unity-Katalogs als Modellregistrierung.
  • Legen Sie den Katalog und das Schema fest, in dem das Modell registriert wird.
  • Lesen Sie die Daten, und speichern Sie sie in Tabellen im Unity-Katalog.
  • Vorverarbeiten Sie die Daten.

Konfigurieren des MLflow-Clients

Standardmäßig erstellt der MLflow-Python-Client Modelle in der Registrierung des Databricks-Arbeitsbereichsmodells. Um Modelle im Unity-Katalog zu speichern, konfigurieren Sie den MLflow-Client wie in der folgenden Zelle dargestellt.

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

In der folgenden Zelle wird der Katalog und das Schema festgelegt, in dem das Modell registriert wird. Sie müssen über das USE CATALOG-Privileg für den Katalog sowie über die Privilegien USE_SCHEMA, CREATE_TABLE und CREATE_MODEL für das Schema verfügen. Ändern Sie bei Bedarf die Katalog- und Schemanamen in der folgenden Zelle.

Weitere Informationen finden Sie in der Unity-Katalogdokumentation.

# 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"

Lesen von Daten und Speichern in Tabellen im Unity-Katalog

Das Dataset ist verfügbar in databricks-datasets. In der folgenden Zelle lesen Sie die Daten aus .csv Dateien in Spark DataFrames. Anschließend schreiben Sie die DataFrames in Tabellen im Unity-Katalog. Dadurch werden die Daten beibehalten, und Sie können steuern, wie sie für andere Personen freigegeben werden.

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")

Vorverarbeitung von Daten

# 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
)

Teil 1: Trainieren eines Klassifizierungsmodells

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

Trainieren Sie als Nächstes einen Klassifizierer im Kontext einer MLflow-Ausführung, wodurch automatisch das trainierte Modell und viele zugeordnete Metriken und Parameter protokolliert werden.

Sie können die Protokollierung mit zusätzlichen Metriken wie der AUC-Bewertung des Modells im Testdatensatz ergänzen.

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))

Anzeigen von MLflow-Ausführungen

Um den protokollierten Trainingslauf anzuzeigen, klicken Sie oben rechts im Notizbuch auf das Symbol "Experiment iconExperiment", um die Experiment-Randleiste einzublenden. Klicken Sie bei Bedarf auf das Aktualisierungssymbol, um die neuesten Ausführungen abzurufen und zu überwachen.

In der rechten Randleiste aufgelistete Experimente

Um die detailliertere MLflow-Experimentseite anzuzeigen, klicken Sie auf das Symbol der Experimentseite. Auf dieser Seite können Sie Durchläufe vergleichen und Details zu bestimmten Durchläufen ansehen. Siehe Nachverfolgen der Modellentwicklung mithilfe von MLflow.

Laden von Modellen

Sie können auch auf die Ergebnisse für eine bestimmte Ausführung mithilfe der MLflow-API zugreifen. Der Code in der folgenden Zelle veranschaulicht, wie das Modell in einem bestimmten MLflow-Lauf geladen und verwendet wird, um Vorhersagen zu erstellen. Außerdem finden Sie Codeausschnitte zum Laden bestimmter Modelle auf der MLflow-Ausführungsseite.

# 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))

Teil 2: Hyperparameteroptimierung

An diesem Punkt haben Sie ein einfaches Modell trainiert und den MLflow-Tracking-Dienst verwendet, um Ihre Arbeit zu organisieren. Als Nächstes können Sie anspruchsvollere Optimierungen mit Optuna durchführen.

Parallele Schulung mit Optuna

Optuna ist eine Open-Source-Python-Bibliothek für die Hyperparameteroptimierung, die horizontal über mehrere Computeressourcen skaliert werden kann. Weitere Informationen zur Verwendung von Optuna in Databricks finden Sie unter Hyperparameter tuning with 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)

Suchläufe zum Abrufen des besten Modells

Da alle Durchläufe von MLflow nachverfolgt werden, können Sie die Metriken und Parameter für den besten Durchlauf mithilfe der MLflow Search-Runs-API abrufen, um den Tuning-Durchlauf mit dem höchsten Test-AUC zu finden.

Dieses abgestimmte Modell sollte besser funktionieren als die einfacheren Modelle, die in Teil 1 trainiert wurden.

# 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)

Teil 3. Speichern von Ergebnissen und Modellen im Unity-Katalog

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")

Teil 4. Bereitstellen des Modells

Nachdem Sie Ihr Modell im Unity-Katalog gespeichert haben, können Sie es mithilfe der Benutzeroberfläche bereitstellen. Die folgenden Anweisungen enthalten eine kurze Beschreibung. Weitere Informationen finden Sie unter Benutzerdefinierte Modellbereitstellungspunkte erstellen.

  1. Klicken Sie in der Randleiste auf Serving, um die Serving-Benutzeroberfläche anzuzeigen.

Modell für die Benutzeroberfläche

  1. Klicken Sie auf "Bereitstellungsendpunkt erstellen".

  2. Geben Sie im Feld "Name " einen Namen für Ihren Endpunkt an.

  3. Im Abschnitt Bereitgestellte Entitäten

    1. Wählen Sie das Feld Entität aus, um das Formular Bereitgestellte Entität auswählen zu öffnen.
    2. Wählen Sie "Meine Modelle" aus– Unity-Katalog. Das Formular wird basierend auf Ihrer Auswahl dynamisch aktualisiert.
    3. Wählen Sie das wine_quality_model und die Modellversion aus, die Sie bereitstellen möchten.
    4. Wählen Sie 100 als Prozentsatz des Datenverkehrs aus, den Sie an Ihr bereitgestelltes Modell weiterleiten möchten.
    5. Wählen Sie "CPU " als Berechnungstyp für dieses Beispiel aus.
    6. Wählen Sie unter Compute Scale-out die Option Klein als die Skalierungsgröße für die Berechnung aus.
  4. Klicke auf Erstellen. Die Seite "Dienstendpunkte" wird angezeigt, wobei der "Dienstendpunktstatus" als "Nicht bereit" angezeigt wird.

  5. Wenn Ihr Endpunkt bereit ist, wählen Sie "Verwenden " aus, um eine Rückschlussanforderung an den Endpunkt zu senden.

Beispiel-Notebook

Erste Schritte: Erstellen Ihres ersten Machine Learning-Modells auf Databricks

Notebook abrufen