Partager via


Tutoriel : Créer votre premier modèle Machine Learning sur Azure Databricks

Cet article explique comment créer un modèle de classification d’apprentissage automatique à l’aide de la bibliothèque scikit-learn sur Azure Databricks.

L’objectif est de créer un modèle de classification pour prédire si un vin est considéré comme « de haute qualité ». Le jeu de données comprend 11 caractéristiques de différents vins (par exemple, la teneur en alcool, l’acide et le sucre résiduel) et un classement de qualité compris entre 1 et 10.

Cet exemple illustre également l’utilisation de MLflow pour suivre le processus de développement de modèles et Hyperopt pour automatiser le réglage des hyperparamètres.

Le jeu de données provient du Référentiel Machine Learning UCI, présenté dans Modeling wine preferences by data mining from physicochemical properties [Cortez et al., 2009].

Avant de commencer

  • Votre espace de travail doit être activé pour le catalogue Unity. Consultez Bien démarrer avec Unity Catalog.
  • Vous devez avoir l’autorisation de créer une ressource de calcul ou d’accéder à une ressource de calcul qui utilise Databricks Runtime pour Machine Learning.
  • Vous devez disposer du privilège USE CATALOG sur un catalogue.
  • Dans ce catalogue, vous devez disposer des privilèges suivants sur un schéma : USE SCHEMA, CREATE TABLEet CREATE MODEL.

Conseil

Tout le code de cet article est disponible dans un notebook que vous pouvez importer directement dans votre espace de travail. Consultez Exemple de notebook : créer un modèle de classification.

Étape 1 : Créer un notebook Databricks

Pour créer un notebook dans votre espace de travail, cliquez sur Nouvelle icôneNouveau dans la barre latérale, puis sur Notebook. Un notebook vide s’ouvre dans l’espace de travail.

Pour en savoir plus sur la création et la gestion des notebooks, consultez Gérer les notebooks.

Étape 2 : Connecter les ressources de calcul

Pour effectuer une analyse exploratoire des données et l’ingénierie des données, vous devez avoir accès au calcul. Les étapes décrites dans cet article nécessitent Databricks Runtime pour Machine Learning. Pour plus d’informations et d’instructions sur la sélection d’une version ML de Databricks Runtime, consultez Databricks Runtime pour Machine Learning.

Dans votre bloc-notes, cliquez sur le menu déroulant Se connecter en haut à droite. Si vous avez accès à une ressource existante qui utilise Databricks Runtime pour Machine Learning, sélectionnez cette ressource dans le menu. Sinon, cliquez sur Créer une ressource... pour configurer une nouvelle ressource de calcul.

Étape 3 : Configurer le registre de modèles, le catalogue et le schéma

Deux étapes importantes sont nécessaires avant de démarrer. Tout d’abord, vous devez configurer le client MLflow afin qu’il utilise Unity Catalog comme registre de modèles. Saisissez le code suivant dans une nouvelle cellule de votre notebook.

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

Vous devez également définir le catalogue et le schéma dans lequel le modèle sera inscrit. Vous devez avoir le privilège USE CATALOG sur le catalogue, ainsi que USE SCHEMA, CREATE TABLE et CREATE MODEL sur le schéma.

Pour plus d’informations sur la façon d’utiliser Unity Catalog, consultez Qu’est-ce que Unity Catalog ?.

Saisissez le code suivant dans une nouvelle cellule de votre notebook.

# If necessary, replace "main" and "default" with a catalog and schema for which you have the required permissions.
CATALOG_NAME = "main"
SCHEMA_NAME = "default"

Étape 4 : Charger des données et créer des tables Unity Catalog

Cet exemple utilise deux fichiers CSV disponibles dans databricks-datasets. Pour savoir comment ingérer vos propres données, consultez les connecteurs Standard dans Lakeflow Connect.

Saisissez le code suivant dans une nouvelle cellule de votre notebook. Ce code effectue les opérations suivantes :

  1. Lire des données depuis winequality-white.csv et winequality-red.csv dans des DataFrames Spark.
  2. Nettoyez les données en remplaçant les espaces dans les noms de colonnes par des traits de soulignement.
  3. Écrivez les DataFrames dans les tables white_wine et red_wine dans le catalogue Unity. L’enregistrement des données dans le catalogue Unity conserve les données et vous permet de contrôler comment les partager avec d’autres utilisateurs.
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")

Étape 5. Prétraiter et fractionner les données

Dans cette étape, vous chargez les données des tables Unity Catalog que vous avez créées à l’étape 4 dans Pandas DataFrames et prétraitez les données. Le code de cette section permet d’effectuer les opérations suivantes :

  1. Chargement des données en tant que Pandas DataFrame.
  2. Ajout d’une colonne booléenne à chaque DataFrame pour distinguer les vins rouges et blancs, puis combinaison des DataFrames dans un nouveau DataFrame, data_df.
  3. Le jeu de données inclut une colonne quality qui évalue les vins de 1 à 10, 10 indiquant la plus haute qualité. Le code transforme cette colonne en deux valeurs de classification : « True » pour indiquer un vin de haute qualité (quality>= 7) et « False » pour indiquer un vin qui n’est pas de haute qualité (quality< 7).
  4. Fractionnement du DataFrame en deux ensembles de données distincts, l’un pour la formation et l’autre pour le test.

Tout d’abord, importez les bibliothèques nécessaires :

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

from hyperopt import fmin, tpe, hp, SparkTrials, Trials, STATUS_OK
from hyperopt.pyll import scope

À présent, chargez et traitez les données :

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

Étape 6. Entraîner le modèle de classification

Cette étape entraîne un classifieur de boosting de gradient à l’aide des paramètres d’algorithme par défaut. Il applique ensuite le modèle résultant au jeu de données de test et calcule, journalise et affiche la zone sous la courbe d’exploitation du récepteur pour évaluer les performances du modèle.

Tout d’abord, activez la journalisation automatique MLflow :

mlflow.autolog()

À présent, démarrez l’exécution de l’entraînement du modèle :

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

Les résultats de la cellule présentent la zone calculée sous la courbe et un tracé de la courbe ROC :

Courbe ROC pour le modèle de classification.

Étape 7. Afficher les exécutions d’expériences dans MLflow

Le suivi des expériences MLflow vous permet de suivre le développement de modèles en produisant un journal d’activités du code et des résultats au fur et à mesure que vous développez des modèles de manière itérative.

Pour afficher les résultats du journal d’activités de l’exécution d’entraînement que vous venez d’exécuter, cliquez sur le lien dans la sortie de la cellule, comme illustré dans l’image suivante.

Lien vers l’expérience dans les résultats de cellule.

La page d’expérience permet de comparer les exécutions et d’afficher les détails des exécutions spécifiques. Cliquez sur le nom d’une exécution pour afficher des détails tels que les valeurs de paramètre et de métrique pour cette exécution. Consultez le suivi des expériences MLflow.

Vous pouvez également afficher les exécutions de l’expérience de votre bloc-notes en cliquant sur dans le coin supérieur droit du bloc-notes.Experiment icon Cela ouvre le panneau latéral de l'expérience, qui affiche un résumé de chaque exécution associée à l'expérience du notebook, y compris les paramètres d’exécution et les métriques. Si nécessaire, cliquez sur l’icône d’actualisation pour extraire et surveiller les dernières exécutions.

La barre latérale de l’expérience s’exécute dans le notebook affiche les dernières exécutions MLflow.

Étape 8 : Utiliser Hyperopt pour le réglage des hyperparamètres

Une étape importante dans le développement d’un modèle ML optimise la précision du modèle en paramétrant les paramètres qui contrôlent l’algorithme, appelés hyperparamètres.

Databricks Runtime ML comprend Hyperopt, une bibliothèque Python pour le réglage des hyperparamètres. Vous pouvez utiliser Hyperopt pour exécuter des balayages d’hyperparamètres et entraîner plusieurs modèles en parallèle, ce qui réduit le temps nécessaire pour optimiser les analyses de performance du modèle. Le suivi MLflow est intégré à Hyperopt afin de consigner automatiquement les modèles et les paramètres. Pour plus d’informations sur l’utilisation de Hyperopt dans Databricks, consultez Réglage des hyperparamètres.

Le code ci-après indique un exemple d’utilisation d’Hyperopt.

# Define the search space to explore
search_space = {
  'n_estimators': scope.int(hp.quniform('n_estimators', 20, 1000, 1)),
  'learning_rate': hp.loguniform('learning_rate', -3, 0),
  'max_depth': scope.int(hp.quniform('max_depth', 2, 5, 1)),
}

def train_model(params):
  # Enable autologging on each worker
  mlflow.autolog()
  with mlflow.start_run(nested=True):
    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)

    # Set the loss to -1*auc_score so fmin maximizes the auc_score
    return {'status': STATUS_OK, 'loss': -1*roc_auc}

# SparkTrials distributes the tuning using Spark workers
# Greater parallelism speeds processing, but each hyperparameter trial has less information from other trials
# On smaller clusters try setting parallelism=2
spark_trials = SparkTrials(
  parallelism=1
)

with mlflow.start_run(run_name='gb_hyperopt') as run:
  # Use hyperopt to find the parameters yielding the highest AUC
  best_params = fmin(
    fn=train_model,
    space=search_space,
    algo=tpe.suggest,
    max_evals=32,
    trials=spark_trials)

Étape 9. Trouver le meilleur modèle et l’inscrire auprès de Unity Catalog

Le code suivant identifie l’exécution qui a produit les meilleurs résultats, comme mesuré par la zone sous la courbe ROC :

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

À l’aide de run_id que vous avez identifié pour le meilleur modèle, le code suivant inscrit ce modèle dans Unity Catalog.

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

Exemple de notebook : créer un modèle de classification

Utilisez le notebook suivant pour effectuer les étapes figurant dans cet article. Pour obtenir des instructions sur l’importation d’un notebook dans un espace de travail Azure Databricks, consultez Importer un notebook.

Créez votre premier modèle Machine Learning avec Databricks

Obtenir le notebook

En savoir plus

Databricks fournit une plateforme unique qui sert chaque étape du développement et de déploiement du ML, des données brutes aux tables d’inférence qui enregistrent chaque requête et réponse pour un modèle servi. Les scientifiques des données, les ingénieurs des données, les ingénieurs ML et DevOps peuvent effectuer leurs tâches à l’aide du même ensemble d’outils et d’une source unique et fiable pour les données.

Pour en savoir plus, consultez les articles suivants :