Kom igång: Skapa din första maskininlärningsmodell på Databricks

Den här exempelanteckningsboken visar hur du tränar en klassificeringsmodell för maskininlärning i Databricks. Databricks Runtime for strojové učenie levereras med många bibliotek förinstallerade, inklusive scikit-learn för tränings- och förbearbetningsalgoritmer, MLflow för att spåra modellutvecklingsprocessen och Optuna för att skala hyperparameterjustering.

I den här notebook-filen skapar du en klassificeringsmodell för att förutsäga om ett vin anses vara av "hög kvalitet". Datamängden består av 11 funktioner i olika viner (till exempel alkoholhalt, surhet och restsocker) och en kvalitetsrankning mellan 1 och 10.

Den här självstudiekursen omfattar:

  • Del 1: Träna en klassificeringsmodell med MLflow-spårning
  • Del 2: Justering av Hyperparameter för att förbättra modellprestanda
  • Del 3: Spara resultat och modeller i Unity Catalog
  • Del 4: Implementera modellen

Mer information om hur du produktionsanpassar maskininlärning på Databricks, inklusive modelllivscykelhantering och modellinferens, finns i ML End to End Example.

Datauppsättningen finns tillgänglig i UCI strojové učenie Repository och presenteras i Modeling wine preferences by data mining from physicochemical properties [Cortez et al., 2009].

Kravspecifikation

Inställningar

I det här avsnittet gör du följande:

  • Konfigurera MLflow-klienten så att den använder Unity Catalog som modellregister.
  • Ange katalogen och schemat där modellen ska registreras.
  • Läs i data och spara dem i tabeller i Unity Catalog.
  • Förbearbeta data.

Konfigurera MLflow-klienten

Som standard skapar MLflow-Python-klienten modeller i databricks-arbetsytemodellregistret. Om du vill spara modeller i Unity Catalog konfigurerar du MLflow-klienten enligt följande cell.

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

Följande cell anger katalogen och schemat där modellen ska registreras. Du måste ha USE CATALOG behörighet för katalogen och USE_SCHEMA, CREATE_TABLE och CREATE_MODEL behörigheter i schemat. Ändra katalog- och schemanamnen i följande cell om det behövs.

Mer information finns i dokumentationen för Unity Catalog.

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

Läsa in data och spara dem i tabeller i Unity Catalog

Datamängden är tillgänglig i databricks-datasets. I följande cell läser du in data från .csv filer till Spark DataFrames. Sedan skriver du DataFrames till tabeller i Unity Catalog. Detta bevarar både data och låter dig styra hur du delar dem med andra.

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

Förbearbeta data

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

Del 1. Träna en klassificeringsmodell

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

Träna sedan en klassificerare inom ramen för en MLflow-körning, som automatiskt loggar den tränade modellen och många associerade mått och parametrar.

Du kan komplettera loggningen med ytterligare mått, till exempel modellens AUC-poäng på testdatauppsättningen.

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

Visa MLflow-körningar

Klicka på ExperimentikonenExperimentikonen längst upp till höger i anteckningsboken för att visa sidofältet för experimentet och se den loggade träningskörningen. Om det behövs klickar du på uppdateringsikonen för att hämta och övervaka de senaste körningarna.

Experiment som visas i det högra sidofältet

Om du vill visa den mer detaljerade MLflow-experimentsidan klickar du på ikonen för experimentsidan. På den här sidan kan du jämföra körningar och visa detaljer för specifika körningar. Se Spåra modellutveckling med MLflow.

Läsa in modeller

Du kan också komma åt resultaten för en specifik körning med hjälp av MLflow-API:et. Koden i följande cell visar hur du läser in modellen som tränats i en viss MLflow-körning och använder den för att göra förutsägelser. Du kan också hitta kodexempel för att ladda specifika modeller på MLflow-körningssidan.

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

Del 2. Finjustering av hyperparametrar

Nu har du tränat en enkel modell och använt tjänsten för MLflow-spårning för att organisera ditt arbete. Därefter kan du utföra mer avancerad justering med optuna.

Parallell träning med Optuna

Optuna är ett bibliotek med öppen källkod Python för hyperparameterjustering som kan skalas horisontellt över flera beräkningsresurser. Mer information om hur du använder Optuna i Databricks finns i Hyperparameterjustering med 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)

Sökkörningar för att hämta den bästa modellen

Eftersom alla körningar spåras av MLflow kan du hämta måtten och parametrarna för den bästa körningen med hjälp av MLflow-sökkörnings-API:et för att hitta finjusteringskörningen med högsta test-AUC.

Den här finjusterade modellen bör fungera bättre än de enklare modeller som tränas i del 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)

Del 3. Spara resultat och modeller i 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")

Del 4. Distribuera modell

När du har sparat din modell i Unity Catalog kan du distribuera den med hjälp av användargränssnittet för servering. Följande instruktioner ger en kort beskrivning. Mer information finns i Skapa anpassade modellserverslutpunkter.

  1. Klicka på Servering i sidopanelen för att visa användargränssnittet för servering.

Modell som betjänar användargränssnittet

  1. Klicka på Skapa serverslutpunkt.

  2. I fältet Namn anger du ett namn för slutpunkten.

  3. I avsnittet Serverade entiteter

    1. Klicka i fältet Entitet för att öppna formuläret Välj hanterad entitet.
    2. Välj Mina modeller – Unity Catalog. Formuläret uppdateras dynamiskt baserat på ditt val.
    3. Välj den wine_quality_model och modellversionen som du vill tillhandahålla.
    4. Välj 100 som procentandel av trafiken som du vill dirigera till din betjänade modell.
    5. Välj CPU som beräkningstyp för det här exemplet.
    6. Under Beräkna utskalning väljer du Liten som beräkningsstorlek för utskalning.
  4. Klicka på Skapa. Sidan Tjänstgörande slutpunkter visas med tjänstgörande slutpunkts tillstånd som Inte redo.

  5. När slutpunkten är Klar väljer du Använd för att skicka en slutsatsdragningsbegäran till slutpunkten.

Exempelanteckningsbok

Kom igång: Skapa din första maskininlärningsmodell på Databricks

Hämta anteckningsbok