Aan de slag: Uw eerste Machine Learning-model bouwen op Databricks

In dit voorbeeldnotebook ziet u hoe u een machine learning-classificatiemodel traint op Databricks. Databricks Runtime voor Machine Learning wordt geleverd met veel bibliotheken die vooraf zijn geïnstalleerd, waaronder scikit-learn voor trainings- en preverwerkingsalgoritmen, MLflow om het modelontwikkelingsproces bij te houden en Optuna voor het schalen van hyperparameters.

In dit notebook maakt u een classificatiemodel om te voorspellen of een wijn wordt beschouwd als 'hoge kwaliteit'. De gegevensset bestaat uit 11 kenmerken van verschillende wijnen (bijvoorbeeld alcoholgehalte, zuurgehalte en restsuiker) en een kwaliteitsclassificatie tussen 1 en 10.

In deze zelfstudie komt het volgende aan bod:

  • Deel 1: Een classificatiemodel trainen met MLflow-tracering
  • Deel 2: Hyperparameterafstemming om de modelprestaties te verbeteren
  • Deel 3: Resultaten en modellen opslaan in Unity Catalog
  • Deel 4: Het model implementeren

Zie het ML End-to-End-end-voorbeeld voor meer informatie over het produceren van machine learning op Databricks, inclusief modellevenscyclusbeheer en modeldeductie.

De gegevensset is beschikbaar in de UCI Machine Learning Repository en wordt gepresenteerd in Modeling wine preferences by data mining op basis van fysisch-chemische eigenschappen [Cortez et al., 2009].

Requirements

Installatie

In deze sectie gaat u als volgt te werk:

  • Configureer de MLflow-client voor het gebruik van Unity Catalog als modelregister.
  • Stel de catalogus en het schema in waar het model wordt geregistreerd.
  • Lees de gegevens en sla deze op in tabellen in Unity Catalog.
  • Verwerkt de gegevens vooraf.

MLflow-client configureren

De MLflow-Python-client maakt standaard modellen in het databricks-werkruimtemodelregister. Als u modellen wilt opslaan in Unity Catalog, configureert u de MLflow-client, zoals wordt weergegeven in de volgende cel.

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

In de volgende cel wordt de catalogus en het schema ingesteld waarin het model wordt geregistreerd. U moet bevoegdheden hebben USE CATALOG voor de catalogus en USE_SCHEMA, CREATE_TABLE en CREATE_MODEL bevoegdheden voor het schema. Wijzig indien nodig de catalogus- en schemanamen in de volgende cel.

Zie de Documentatie voor Unity Catalog voor meer informatie.

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

Gegevens lezen en opslaan in tabellen in Unity Catalog

De gegevensset is beschikbaar in databricks-datasets. In de volgende cel leest u de gegevens uit .csv bestanden in Spark DataFrames. Vervolgens schrijft u de DataFrames naar tabellen in Unity Catalog. Hierdoor blijven de gegevens behouden en kunt u bepalen hoe u deze met anderen kunt delen.

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

Gegevens vooraf verwerken

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

Deel 1. Een classificatiemodel trainen

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

Train vervolgens een classificatie binnen de context van een MLflow-uitvoering, waarmee automatisch het getrainde model en veel bijbehorende metrische gegevens en parameters worden geregistreerd.

U kunt de logboekregistratie aanvullen met aanvullende metrische gegevens, zoals de AUC-score van het model op de testgegevensset.

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-uitvoeringen weergeven

Om de gelogde trainingsuitvoering te bekijken, klikt u op het Experiment-pictogram in de rechterbovenhoek van het notitieblok om de zijbalk van het experiment weer te geven. Klik zo nodig op het vernieuwingspictogram om de meest recente uitvoeringen op te halen en te controleren.

Experimenten die worden vermeld in de rechterzijbalk

Als u de gedetailleerdere MLflow-experimentpagina wilt weergeven, klikt u op het pictogram van de experimentpagina. Op deze pagina kunt u uitvoeringen vergelijken en details voor specifieke uitvoeringen bekijken. Zie Modelontwikkeling bijhouden met behulp van MLflow.

Modellen laden

U kunt ook toegang krijgen tot de resultaten voor een specifieke uitvoering met behulp van de MLflow-API. De code in de volgende cel laat zien hoe u het model laadt dat is getraind in een bepaalde MLflow-uitvoering en deze gebruikt om voorspellingen te doen. U kunt ook codefragmenten vinden voor het laden van specifieke modellen op de MLflow-uitvoeringspagina.

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

Deel 2. Hyperparameteroptimalisatie

Op dit moment hebt u een eenvoudig model getraind en de MLflow-traceringsservice gebruikt om uw werk te organiseren. Vervolgens kunt u geavanceerdere afstemming uitvoeren met Optuna.

Parallelle training met optuna

Optuna is een opensource-Python-bibliotheek voor het afstemmen van hyperparameters die horizontaal kunnen worden geschaald over meerdere rekenresources. Zie Hyperparameter-afstemming met Optuna voor meer informatie over het gebruik van Optuna in Databricks.

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)

Voer zoekacties uit om het beste model op te halen

Omdat alle uitvoeringen worden bijgehouden door MLflow, kunt u de metrische gegevens en parameters ophalen voor de beste uitvoering met behulp van de MLflow-zoekuitvoerings-API om de afstemmingsuitvoering te vinden met de hoogste test-auc.

Dit afgestemde model moet beter presteren dan de eenvoudigere modellen die zijn getraind in deel 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)

Deel 3. Resultaten en modellen opslaan in Unity Catalog

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

Deel 4. Model implementeren

Nadat u uw model hebt opgeslagen in Unity Catalog, kunt u het uitrollen met behulp van de Serving-UI. De volgende instructies geven een korte beschrijving. Zie Aangepast model maken voor eindpunten voor meer informatie.

  1. Klik op Serveren in de zijbalk om de gebruikersinterface van de server weer te geven.

Model voor gebruikersinterface

  1. Klik op Een service-eindpunt maken.

  2. Geef in het veld Naam een naam op voor uw eindpunt.

  3. In de sectie Geserveerde entiteiten

    1. Klik in het veld Entiteit om het formulier Bediende entiteit selecteren te openen.
    2. Selecteer Mijn modellen- Unity Catalog. Het formulier wordt dynamisch bijgewerkt op basis van uw selectie.
    3. Selecteer de wine_quality_model en modelversie die u wilt gebruiken.
    4. Selecteer 100 als het percentage verkeer dat u wilt routeren naar uw geleverd model.
    5. Selecteer CPU als het rekentype voor dit voorbeeld.
    6. Selecteer onder Compute Scale-outKlein als de schaalgrootte voor uitschaling van de rekenkracht.
  4. Klik op Create. De pagina Eindpunten voor het serveren wordt weergegeven met de status Van het servereindpunt die wordt weergegeven als Niet gereed.

  5. Wanneer uw eindpunt gereed is, selecteert u Gebruiken om een deductieaanvraag naar het eindpunt te verzenden.

Voorbeeld van notebook

Aan de slag: Uw eerste Machine Learning-model bouwen op Databricks

Notitieblok ophalen