Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Cet exemple de notebook montre comment entraîner un modèle de classification Machine Learning sur Databricks. Databricks Runtime pour Machine Learning est fourni avec de nombreuses bibliothèques préinstallées, notamment scikit-learn pour l’apprentissage et les algorithmes de prétraitement, MLflow pour suivre le processus de développement de modèle et Optuna pour mettre à l’échelle le réglage des hyperparamètres.
Dans ce notebook, vous créez 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.
Ce didacticiel contient les sections suivantes :
- Partie 1 : Entraîner un modèle de classification avec le suivi MLflow
- Partie 2 : Réglage des hyperparamètres pour améliorer les performances du modèle
- Partie 3 : Enregistrer les résultats et les modèles dans le catalogue Unity
- Partie 4 : Déployer le modèle
Pour plus d’informations sur la productionnalisation du Machine Learning sur Databricks, notamment la gestion du cycle de vie des modèles et l’inférence de modèle, consultez l’Exemple ML de bout en bout.
Le jeu de données est disponible à partir du référentiel de UCI Machine Learning et est présenté dans Modeling wine preferences by data mining from physicochemical properties [Cortez et al., 2009].
Exigences
- Cluster exécutant Databricks Runtime 17.3 LTS ML ou version ultérieure. Si vous exécutez Databricks Runtime 16.4 LTS ML ou ci-dessous, consultez tutoriel : Créer votre premier modèle Machine Learning sur Databricks (Hyperopt).
Paramétrage
Dans cette section, procédez comme suit :
- Configurez le client MLflow pour utiliser le catalogue Unity comme registre de modèles.
- Définissez le catalogue et le schéma où le modèle sera inscrit.
- Lisez les données et enregistrez-les dans les tables du catalogue Unity.
- Prétraitez les données.
Configurer le client MLflow
Par défaut, le client MLflow Python crée des modèles dans le registre de modèles de l’espace de travail Databricks. Pour enregistrer des modèles dans le catalogue Unity, configurez le client MLflow comme indiqué dans la cellule suivante.
import mlflow
mlflow.set_registry_uri("databricks-uc")
La cellule suivante définit le catalogue et le schéma où le modèle sera inscrit. Vous devez disposer de privilèges USE CATALOG sur le catalogue, et des privilèges USE_SCHEMA, CREATE_TABLE et CREATE_MODEL sur le schéma. Modifiez le catalogue et les noms de schéma dans la cellule suivante si nécessaire.
Pour plus d’informations, consultez la documentation du catalogue 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"
Lire les données et les enregistrer dans des tables dans le catalogue Unity
Le jeu de données est disponible dans databricks-datasets. Dans la cellule suivante, vous importez les données des fichiers .csv dans des Spark DataFrames. Vous écrivez ensuite les DataFrames dans des tables du catalogue Unity. Ces deux éléments conservent les données et vous permettent de contrôler comment les partager avec d’autres personnes.
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")
Prétraitement des données
# 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
)
Partie 1. Entraîner un modèle de classification
# Enable MLflow autologging for this notebook
mlflow.autolog()
Ensuite, entraînez un classifieur dans le contexte d’une exécution MLflow, qui journalise automatiquement le modèle entraîné et de nombreux paramètres et métriques associés.
Vous pouvez compléter la journalisation avec des métriques supplémentaires telles que le score AUC du modèle sur le jeu de données de test.
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))
Afficher les exécutions MLflow
Pour afficher l'exécution de l'entraînement enregistrée, cliquez sur l'icône en haut à droite du bloc-notes pour faire apparaître la barre latérale de l'expérimentation.
Si nécessaire, cliquez sur l’icône d’actualisation pour extraire et surveiller les dernières exécutions.
Pour afficher la page d’expérience MLflow plus détaillée, cliquez sur l’icône de page d’expérience. Cette page vous permet de comparer les exécutions et d’afficher les détails des exécutions spécifiques. Voir Suivre le développement de modèles à l’aide de MLflow.
Charger des modèles
Vous pouvez également accéder aux résultats d’une exécution spécifique à l’aide de l’API MLflow. Le code de la cellule suivante montre comment charger le modèle entraîné dans une exécution MLflow donnée et l’utiliser pour effectuer des prédictions. Vous pouvez également trouver des extraits de code pour charger des modèles spécifiques sur la page d’exécution 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))
Partie 2. Optimisation des hyperparamètres
À ce stade, vous avez formé un modèle simple et utilisé le service de suivi MLflow pour organiser votre travail. Ensuite, vous pouvez effectuer un réglage plus sophistiqué à l’aide d’Optuna.
Formation parallèle à l’aide d’Optuna
Optuna est une bibliothèque Python open source pour le réglage des hyperparamètres qui offre une scalabilité horizontale sur plusieurs capacités de calcul. Pour plus d’informations sur l’utilisation d’Optuna dans Databricks, consultez Optimisation des hyperparamètres avec 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)
Exécutions de recherche pour récupérer le meilleur modèle
Étant donné que toutes les exécutions sont suivies par MLflow, vous pouvez récupérer les métriques et les paramètres de la meilleure exécution à l’aide de l’API de recherche d'exécutions de MLflow pour trouver l’exécution de réglage avec le taux d'AUC de test le plus élevé.
Ce modèle paramétré doit fonctionner mieux que les modèles plus simples entraînés dans la partie 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)
Partie 3. Enregistrer les résultats et les modèles dans le catalogue 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")
Partie 4. Déployer un modèle
Après avoir enregistré votre modèle dans le catalogue Unity, vous pouvez le déployer à l’aide de l’interface utilisateur de service. Les instructions suivantes fournissent une brève description. Pour plus d'informations, consultez Créer des points d'accès de modèles personnalisés.
- Cliquez sur Mise en service dans la barre latérale pour afficher l’interface utilisateur de mise en service.
Cliquez sur Créer un point de service.
Dans le champ Nom , indiquez un nom pour votre point de terminaison.
Dans la section Entités servies
- Cliquez sur le champ Entités pour ouvrir le formulaire Sélectionner une entité servie.
- Sélectionnez Mes modèles - Catalogue Unity. Le formulaire est mis à jour dynamiquement en fonction de votre sélection.
- Sélectionnez la version
wine_quality_modeldu modèle que vous souhaitez déployer. - Sélectionnez 100 comme pourcentage de trafic que vous souhaitez acheminer vers votre modèle servi.
- Sélectionnez l’UC comme type de calcul pour cet exemple.
- Sous Scale-out de calcul, sélectionnez Small comme taille de scale-out de calcul.
Cliquez sur Créer. La page Points de terminaison de service s’affiche avec l’état de point de terminaison De service affiché comme Non prêt.
Lorsque votre point de terminaison est prêt, sélectionnez Utiliser pour envoyer une demande d’inférence au point de terminaison.