1. Présentation
Dans cet atelier, vous allez utiliser l'outil de simulation What-If pour analyser un modèle XGBoost entraîné sur des données financières. Après avoir analysé le modèle, vous le déploierez sur la nouvelle plate-forme Vertex AI de Cloud.
Objectifs de l'atelier
Vous allez apprendre à effectuer les opérations suivantes :
- Entraîner un modèle XGBoost sur un ensemble de données hypothécaires public dans un notebook hébergé
- Analyser le modèle à l'aide de l'outil de simulation What-If
- Déployer le modèle XGBoost sur Vertex AI
Le coût total d'exécution de cet atelier sur Google Cloud est d'environ 1$.
2. Présentation de Vertex AI
Cet atelier utilise la toute dernière offre de produits d'IA de Google Cloud. Vertex AI simplifie l'expérience de développement en intégrant toutes les offres de ML de Google Cloud. Auparavant, les modèles entraînés avec AutoML et les modèles personnalisés étaient accessibles depuis des services distincts. La nouvelle offre regroupe ces deux types de modèles mais aussi d'autres nouveaux produits en une seule API. Vous pouvez également migrer des projets existants vers Vertex AI. Pour envoyer un commentaire, consultez la page d'assistance.
Vertex AI comprend de nombreux produits différents qui permettent de gérer les workflows de ML de bout en bout. Cet atelier se concentre sur les produits mis en évidence ci-dessous : Prediction et Notebooks.

3. Présentation rapide de XGBoost
XGBoost est un framework de machine learning qui utilise des arbres de décision et le boosting de gradient pour créer des modèles prédictifs. Il fonctionne en combinant plusieurs arbres de décision en fonction du score associé aux différents nœuds feuilles d'un arbre.
Le schéma ci-dessous est une visualisation d'un modèle d'arbre de décision simple qui évalue si un match sportif doit être joué en fonction des prévisions météorologiques :

Pourquoi utilisons-nous XGBoost pour ce modèle ? Alors que les réseaux de neurones traditionnels se sont avérés les plus performants sur des données non structurées telles que des images et du texte, les arbres de décision sont souvent extrêmement performants sur des données structurées telles que l'ensemble de données hypothécaires que nous utiliserons dans cet atelier de programmation.
4. Configurez votre environnement.
Pour suivre cet atelier de programmation, vous aurez besoin d'un projet Google Cloud Platform dans lequel la facturation est activée. Pour créer un projet, suivez ces instructions.
Étape 1 : Activez l'API Compute Engine
Accédez à Compute Engine et cliquez sur Activer si ce n'est pas déjà fait. Vous en aurez besoin pour créer votre instance de notebook.
Étape 2 : Activez l'API Vertex AI
Accédez à la section Vertex de la console Cloud, puis cliquez sur Activer l'API Vertex AI.

Étape 3 : Créez une instance Notebooks
Dans la section Vertex de la console Cloud, cliquez sur Notebooks :

Sélectionnez ensuite Nouvelle instance. Sélectionnez ensuite le type d'instance TensorFlow Enterprise 2.3 sans GPU :

Utilisez les options par défaut, puis cliquez sur Créer. Une fois l'instance créée, sélectionnez Ouvrir JupyterLab.
Étape 4 : Installez XGBoost
Une fois votre instance JupyterLab ouverte, vous devez ajouter le package XGBoost.
Pour ce faire, sélectionnez Terminal dans le lanceur :

Exécutez ensuite la commande suivante pour installer la dernière version de XGBoost compatible avec Vertex AI :
pip3 install xgboost==1.2
Une fois cette opération terminée, ouvrez une instance de notebook Python 3 à partir du lanceur. Vous pouvez commencer à utiliser votre notebook.
Étape 5 : Importez des packages Python
Dans la première cellule de votre notebook, ajoutez les importations suivantes et exécutez la cellule. Pour l'exécuter, appuyez sur le bouton flèche droite dans le menu supérieur ou sur Commande+Entrée :
import pandas as pd
import xgboost as xgb
import numpy as np
import collections
import witwidget
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.utils import shuffle
from witwidget.notebook.visualization import WitWidget, WitConfigBuilder
5. Télécharger et traiter des données
Nous allons utiliser un ensemble de données hypothécaires provenant de ffiec.gov pour entraîner un modèle XGBoost. Nous avons effectué un prétraitement sur l'ensemble de données d'origine et créé une version plus petite que vous pouvez utiliser pour entraîner le modèle. Le modèle prédira si une demande de prêt hypothécaire particulière sera approuvée ou non.
Étape 1 : Téléchargez l'ensemble de données prétraité
Nous avons mis à votre disposition une version de l'ensemble de données dans Google Cloud Storage. Vous pouvez la télécharger en exécutant la commande gsutil suivante dans votre notebook Jupyter :
!gsutil cp 'gs://mortgage_dataset_files/mortgage-small.csv' .
Étape 2 : Lisez l'ensemble de données avec Pandas
Avant de créer notre DataFrame Pandas, nous allons créer un dict du type de données de chaque colonne afin que Pandas lise correctement notre ensemble de données :
COLUMN_NAMES = collections.OrderedDict({
'as_of_year': np.int16,
'agency_code': 'category',
'loan_type': 'category',
'property_type': 'category',
'loan_purpose': 'category',
'occupancy': np.int8,
'loan_amt_thousands': np.float64,
'preapproval': 'category',
'county_code': np.float64,
'applicant_income_thousands': np.float64,
'purchaser_type': 'category',
'hoepa_status': 'category',
'lien_status': 'category',
'population': np.float64,
'ffiec_median_fam_income': np.float64,
'tract_to_msa_income_pct': np.float64,
'num_owner_occupied_units': np.float64,
'num_1_to_4_family_units': np.float64,
'approved': np.int8
})
Nous allons ensuite créer un DataFrame en lui transmettant les types de données que nous avons spécifiés ci-dessus. Il est important de mélanger nos données au cas où l'ensemble de données d'origine serait ordonné d'une manière spécifique. Pour ce faire, nous utilisons un utilitaire sklearn appelé shuffle, que nous avons importé dans la première cellule :
data = pd.read_csv(
'mortgage-small.csv',
index_col=False,
dtype=COLUMN_NAMES
)
data = data.dropna()
data = shuffle(data, random_state=2)
data.head()
data.head() nous permet de prévisualiser les cinq premières lignes de notre ensemble de données dans Pandas. Une fois la cellule ci-dessus exécutée, vous devriez obtenir un résultat semblable à celui-ci :

Ce sont les caractéristiques que nous allons utiliser pour entraîner notre modèle. Si vous faites défiler l'écran jusqu'à la fin, vous verrez la dernière colonne approved, qui est ce que nous prédisons. La valeur 1 indique qu'une demande particulière a été approuvée, et 0 qu'elle a été refusée.
Pour afficher la distribution des valeurs approuvées / refusées dans l'ensemble de données et créer un tableau NumPy des libellés, exécutez la commande suivante :
# Class labels - 0: denied, 1: approved
print(data['approved'].value_counts())
labels = data['approved'].values
data = data.drop(columns=['approved'])
Environ 66 % de l'ensemble de données contient des demandes approuvées.
Étape 3 : Créez une colonne factice pour les valeurs catégorielles
Cet ensemble de données contient un mélange de valeurs catégorielles et numériques, mais XGBoost exige que toutes les caractéristiques soient numériques. Au lieu de représenter les valeurs catégorielles à l'aide de l'encodage one-hot, nous allons tirer parti de la fonction Pandas get_dummies pour notre modèle XGBoost.
get_dummies prend une colonne avec plusieurs valeurs possibles et la convertit en une série de colonnes contenant chacune uniquement des 0 et des 1. Par exemple, si nous avions une colonne "couleur" avec les valeurs possibles "bleu" et "rouge", get_dummies la transformerait en deux colonnes appelées "color_blue" et "color_red" avec toutes les valeurs booléennes 0 et 1.
Pour créer des colonnes factices pour nos caractéristiques catégorielles, exécutez le code suivant :
dummy_columns = list(data.dtypes[data.dtypes == 'category'].index)
data = pd.get_dummies(data, columns=dummy_columns)
data.head()
Lorsque vous prévisualisez les données cette fois-ci, vous voyez des caractéristiques uniques (comme purchaser_type illustré ci-dessous) divisées en plusieurs colonnes :

Étape 4 : Divisez les données en ensembles d'entraînement et de test
Un concept important dans le machine learning est la division entraînement / test. Nous allons prendre la majorité de nos données et les utiliser pour entraîner notre modèle, et nous allons mettre de côté le reste pour tester notre modèle sur des données qu'il n'a jamais vues auparavant.
Ajoutez le code suivant à votre notebook, qui utilise la fonction Scikit-learn train_test_split pour diviser nos données :
x,y = data.values,labels
x_train,x_test,y_train,y_test = train_test_split(x,y)
Vous pouvez maintenant créer et entraîner votre modèle.
6. Créez, entraînez et évaluez un modèle XGBoost
Étape 1 : Définissez et entraînez le modèle XGBoost
Créer un modèle dans XGBoost est simple. Nous allons utiliser la classe XGBClassifier pour créer le modèle, et nous n'avons qu'à transmettre le bon paramètre objective pour notre tâche de classification spécifique. Dans ce cas, nous utilisons reg:logistic, car nous avons un problème de classification binaire et nous voulons que le modèle génère une seule valeur comprise entre 0 et 1 : 0 pour non approuvé et 1 pour approuvé.
Le code suivant crée un modèle XGBoost :
model = xgb.XGBClassifier(
objective='reg:logistic'
)
Vous pouvez entraîner le modèle avec une seule ligne de code, en appelant la méthode fit() et en lui transmettant les données et les libellés d'entraînement.
model.fit(x_train, y_train)
Étape 2 : Évaluez la précision de votre modèle
Nous pouvons maintenant utiliser notre modèle entraîné pour générer des prédictions sur nos données de test avec la fonction predict().
Nous allons ensuite utiliser la fonction accuracy_score() de Scikit-learn pour calculer la précision de notre modèle en fonction de ses performances sur nos données de test. Nous allons lui transmettre les valeurs de vérité terrain ainsi que les valeurs prédites du modèle pour chaque exemple de notre ensemble de test :
y_pred = model.predict(x_test)
acc = accuracy_score(y_test, y_pred.round())
print(acc, '\n')
Vous devriez obtenir une précision d'environ 87 %, mais la vôtre variera légèrement, car il existe toujours un élément de hasard dans le machine learning.
Étape 3 : Enregistrez votre modèle
Pour déployer le modèle, exécutez le code suivant pour l'enregistrer dans un fichier local :
model.save_model('model.bst')
7. Utilisez l'outil de simulation What-If pour interpréter votre modèle
Étape 1 : Créez la visualisation de l'outil de simulation What-If
Pour connecter l'outil de simulation What-If à votre modèle local, vous devez lui transmettre un sous-ensemble de vos exemples de test ainsi que les valeurs de vérité terrain pour ces exemples. Créons un tableau NumPy de 500 de nos exemples de test ainsi que leurs libellés de vérité terrain :
num_wit_examples = 500
test_examples = np.hstack((x_test[:num_wit_examples],y_test[:num_wit_examples].reshape(-1,1)))
L'instanciation de l'outil de simulation What-If est aussi simple que la création d'un objet WitConfigBuilder et la transmission du modèle que nous souhaitons analyser.
Comme l'outil de simulation What-If attend une liste de scores pour chaque classe de notre modèle (dans ce cas, 2), nous allons utiliser la méthode predict_proba de XGBoost avec l'outil de simulation What-If :
config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
.set_custom_predict_fn(model.predict_proba)
.set_target_feature('mortgage_status')
.set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)
Notez que le chargement de la visualisation prendra une minute. Une fois le chargement terminé, vous devriez voir ce qui suit :

L'axe des y nous montre la prédiction du modèle, avec 1 comme prédiction approved à haute confiance et 0 comme prédiction denied à haute confiance. L'axe des x n'est que la répartition de tous les points de données chargés.
Étape 2 : Explorez les points de données individuels
La vue par défaut de l'outil de simulation What-If est l'onglet Éditeur de points de données. Vous pouvez cliquer sur n'importe quel point de données individuel pour afficher ses caractéristiques, modifier les valeurs des caractéristiques et voir comment cette modification affecte la prédiction du modèle sur un point de données individuel.
Dans l'exemple ci-dessous, nous avons choisi un point de données proche du seuil de 0,5. La demande de prêt hypothécaire associée à ce point de données particulier provient du CFPB. Nous avons modifié cette caractéristique en 0 et également modifié la valeur de agency_code_Department of Housing and Urban Development (HUD) en 1 pour voir ce qui se passerait pour la prédiction du modèle si ce prêt provenait plutôt du HUD :

Comme nous pouvons le voir dans la partie inférieure gauche de l'outil de simulation What-If, la modification de cette caractéristique a considérablement réduit la prédiction approved du modèle de 32 %. Cela peut indiquer que l'agence d'origine d'un prêt a un impact important sur la sortie du modèle, mais nous devrons effectuer une analyse plus approfondie pour en être sûrs.
Dans la partie inférieure gauche de l'interface utilisateur, nous pouvons également voir la valeur de vérité terrain pour chaque point de données et la comparer à la prédiction du modèle :

Étape 3 : Effectuez une analyse contrefactuelle
Cliquez ensuite sur n'importe quel point de données et déplacez le curseur Afficher le point de données contrefactuel le plus proche vers la droite :

Cette sélection vous montre le point de données qui présente les valeurs de caractéristiques les plus similaires à celui que vous avez sélectionné à l'origine, mais la prédiction opposée. Vous pouvez ensuite parcourir les valeurs des caractéristiques pour voir où les deux points de données diffèrent (les différences sont mises en surbrillance en vert et en gras).
Étape 4 : Examinez les graphiques de dépendance partielle
Pour voir comment chaque caractéristique affecte les prédictions du modèle dans leur ensemble, cochez la case Graphiques de dépendance partielle et assurez-vous que l'option Graphiques de dépendance partielle globaux est sélectionnée :

Nous pouvons voir ici que les prêts provenant du HUD ont une probabilité légèrement plus élevée d'être refusés. Le graphique a cette forme, car le code d'agence est une caractéristique booléenne. Les valeurs ne peuvent donc être que 0 ou 1.
applicant_income_thousands est une caractéristique numérique. Dans le graphique de dépendance partielle, nous pouvons voir qu'un revenu plus élevé augmente légèrement la probabilité d'approbation d'une demande, mais seulement jusqu'à environ 200 000 $. Au-delà de 200 000 $, cette caractéristique n'a pas d'incidence sur la prédiction du modèle.
Étape 5 : Explorez les performances globales et l'équité
Accédez ensuite à l'onglet Performances et équité. Il affiche les statistiques de performances globales sur les résultats du modèle sur l'ensemble de données fourni, y compris les matrices de confusion, les courbes PR et les courbes ROC.
Sélectionnez mortgage_status comme caractéristique de vérité terrain pour afficher une matrice de confusion :

Cette matrice de confusion montre les prédictions correctes et incorrectes de notre modèle en tant que pourcentage du total. Si vous additionnez les carrés Oui réel / Oui prédit et Non réel / Non prédit , vous devriez obtenir la même précision que votre modèle (dans ce cas, environ 87 %, bien que votre modèle puisse varier légèrement, car l'entraînement des modèles de ML comporte un élément de hasard).
Vous pouvez également tester le curseur de seuil, en augmentant et en diminuant le score de classification positive que le modèle doit renvoyer avant de décider de prédire approved pour le prêt, et voir comment cela modifie la précision, les faux positifs et les faux négatifs. Dans ce cas, la précision est la plus élevée autour d'un seuil de 0,55.
Ensuite, dans le menu déroulant de gauche Découper par, sélectionnez loan_purpose_Home_purchase :

Vous verrez maintenant les performances sur les deux sous-ensembles de vos données : la tranche "0" s'affiche lorsque le prêt n'est pas destiné à l'achat d'une maison, et la tranche "1" lorsque le prêt est destiné à l'achat d'une maison. Consultez la précision, le taux de faux positifs et le taux de faux négatifs entre les deux tranches pour rechercher les différences de performances.
Si vous développez les lignes pour examiner les matrices de confusion, vous pouvez voir que le modèle prédit "approuvé" pour environ 70 % des demandes de prêt pour l'achat d'une maison et seulement 46 % des prêts qui ne sont pas destinés à l'achat d'une maison (les pourcentages exacts varient selon votre modèle) :

Si vous sélectionnez Parité démographique dans les boutons radio de gauche, les deux seuils seront ajustés de sorte que le modèle prédise approved pour un pourcentage similaire de candidats dans les deux tranches. Quel est l'impact sur la précision, les faux positifs et les faux négatifs pour chaque tranche ?
Étape 6 : Explorez la distribution des caractéristiques
Enfin, accédez à l'onglet Caractéristiques de l'outil de simulation What-If. Il affiche la distribution des valeurs pour chaque caractéristique de votre ensemble de données :

Vous pouvez utiliser cet onglet pour vous assurer que votre ensemble de données est équilibré. Par exemple, il semble que très peu de prêts dans l'ensemble de données proviennent de la Farm Service Agency. Pour améliorer la précision du modèle, nous pourrions envisager d'ajouter davantage de prêts de cette agence si les données sont disponibles.
Nous avons décrit ici quelques idées d'exploration de l'outil de simulation What-If. N'hésitez pas à continuer à jouer avec l'outil. Il existe de nombreux autres domaines à explorer.
8. Déployer le modèle dans Vertex AI
Notre modèle fonctionne en local, mais il serait intéressant de pouvoir effectuer des prédictions n'importe où (et pas seulement dans ce notebook). Au cours de cette étape, nous allons le déployer dans le cloud.
Étape 1 : Créez un bucket Cloud Storage pour notre modèle
Commençons par définir des variables d'environnement que nous utiliserons tout au long de cet atelier de programmation. Renseignez les valeurs ci-dessous avec le nom de votre projet Google Cloud, le nom du bucket Cloud Storage que vous souhaitez créer (doit être globalement unique) et le nom de la version de la première version de votre modèle :
# Update the variables below to your own Google Cloud project ID and GCS bucket name. You can leave the model name we've specified below:
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
MODEL_NAME = 'xgb_mortgage'
Nous allons maintenant créer un bucket de stockage pour stocker notre fichier de modèle XGBoost. Nous allons pointer Vertex AI vers ce fichier lors du déploiement.
Exécutez cette commande gsutil à partir de votre notebook pour créer un bucket de stockage régional :
!gsutil mb -l us-central1 $MODEL_BUCKET
Étape 2 : Copiez le fichier de modèle dans Cloud Storage
Nous allons ensuite copier notre fichier de modèle XGBoost enregistré dans Cloud Storage. Exécutez la commande gsutil suivante :
!gsutil cp ./model.bst $MODEL_BUCKET
Accédez au navigateur de stockage dans votre console Cloud pour vérifier que le fichier a été copié :

Étape 3 : Créez le modèle et déployez-le sur un point de terminaison
Nous allons bientôt pouvoir déployer le modèle dans le cloud. Dans Vertex AI, un modèle peut contenir plusieurs points de terminaison. Nous allons d'abord créer un modèle, puis un point de terminaison dans ce modèle, et le déployer.
Commencez par utiliser la CLI gcloud pour créer votre modèle :
!gcloud beta ai models upload \
--display-name=$MODEL_NAME \
--artifact-uri=$MODEL_BUCKET \
--container-image-uri=us-docker.pkg.dev/cloud-aiplatform/prediction/xgboost-cpu.1-2:latest \
--region=us-central1
Le paramètre artifact-uri pointe vers l'emplacement de stockage où vous avez enregistré votre modèle XGBoost. Le paramètre container-image-uri indique à Vertex AI le conteneur prédéfini à utiliser pour la diffusion. Une fois cette commande terminée, accédez à la section des modèles de votre console Vertex pour obtenir l'ID de votre nouveau modèle. Vous le trouverez ici :

Copiez cet ID et enregistrez-le dans une variable :
MODEL_ID = "your_model_id"
Il est maintenant temps de créer un point de terminaison dans ce modèle. Nous pouvons le faire avec cette commande gcloud :
!gcloud beta ai endpoints create \
--display-name=xgb_mortgage_v1 \
--region=us-central1
Une fois cette opération terminée, vous devriez voir l'emplacement de votre point de terminaison enregistré dans la sortie de notre notebook. Recherchez la ligne indiquant que le point de terminaison a été créé avec un chemin semblable à celui-ci : projects/project_ID/locations/us-central1/endpoints/endpoint_ID. Remplacez ensuite les valeurs ci-dessous par les ID de votre point de terminaison créé ci-dessus :
ENDPOINT_ID = "your_endpoint_id"
Pour déployer votre point de terminaison, exécutez la commande gcloud ci-dessous :
!gcloud beta ai endpoints deploy-model $ENDPOINT_ID \
--region=us-central1 \
--model=$MODEL_ID \
--display-name=xgb_mortgage_v1 \
--machine-type=n1-standard-2 \
--traffic-split=0=100
Le déploiement du point de terminaison prendra environ 5 à 10 minutes. Pendant le déploiement de votre point de terminaison, accédez à la section des modèles de votre console. Cliquez sur votre modèle. Vous devriez voir votre point de terminaison en cours de déploiement :

Une fois le déploiement terminé, une coche verte s'affiche à la place de l'icône de chargement.
Étape 4 : Testez le modèle déployé
Pour vous assurer que votre modèle déployé fonctionne, testez-le à l'aide de gcloud pour effectuer une prédiction. Commencez par enregistrer un fichier JSON avec un exemple de notre ensemble de test :
%%writefile predictions.json
{
"instances": [
[2016.0, 1.0, 346.0, 27.0, 211.0, 4530.0, 86700.0, 132.13, 1289.0, 1408.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0]
]
}
Testez votre modèle en exécutant cette commande gcloud :
!gcloud beta ai endpoints predict $ENDPOINT_ID \
--json-request=predictions.json \
--region=us-central1
La prédiction de votre modèle doit s'afficher dans la sortie. Cet exemple particulier a été approuvé. Vous devriez donc voir une valeur proche de 1.
9. Nettoyage
Si vous souhaitez continuer à utiliser ce notebook, nous vous recommandons de le désactiver quand vous ne vous en servez pas. À partir de l'interface utilisateur de Notebooks dans la console Cloud, sélectionnez le notebook, puis cliquez sur Arrêter :

Si vous souhaitez supprimer toutes les ressources que vous avez créées dans cet atelier, supprimez simplement l'instance de notebook au lieu de l'arrêter.
Pour supprimer le point de terminaison que vous avez déployé, accédez à la section Points de terminaison de votre console Vertex et cliquez sur l'icône de suppression :

Pour supprimer le bucket de stockage, utilisez le menu de navigation de la console Cloud pour accéder à Stockage, sélectionnez votre bucket, puis cliquez sur "Supprimer" :
