Analyser un modèle de ML financier déployé sur Cloud AI Platform avec l'outil de simulation What-If

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 et déployé sur Cloud AI Platform.

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écaire public dans AI Platform Notebooks
  • Déployer le modèle XGBoost sur AI Platform
  • Analyser le modèle à l'aide de l'outil de simulation What-If

Le coût total d'exécution de cet atelier sur Google Cloud est d'environ 1 $.

2. Présentation rapide de XGBoost

XGBoost est un framework de machine learning qui utilise des arbres de décision et l'optimisation de gradient pour créer des modèles prédictifs. Il assemble plusieurs arbres de décision en fonction du score associé aux différents nœuds feuilles d'un arbre.

Le diagramme ci-dessous est une visualisation d'un modèle d'arbre de décision simple qui évalue la nécessité de jouer à un match en fonction des prévisions météorologiques:

308a0bfc70733abf.png

Pourquoi utilisons-nous XGBoost pour ce modèle ? Bien qu'il s'avère que les réseaux de neurones traditionnels fonctionnent mieux sur des données non structurées comme les images et le texte, les arbres de décision sont souvent très performants sur les données structurées, comme l'ensemble de données hypothécaire que nous utiliserons dans cet atelier de programmation.

3. Configurer 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 Cloud AI Platform Models

Accédez à la section Modèles AI Platform de Cloud Console, puis cliquez sur "Activer" si elle n'est pas déjà activée.

d0d38662851c6af3.png

Étape 2: 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 3: Créez une instance AI Platform Notebooks

Accédez à la section AI Platform Notebooks de la console Cloud, puis cliquez sur Nouvelle instance. Sélectionnez ensuite le dernier type d'instance TF Enterprise 2.x sans GPU:

7d16190440ab2e9c.png

Utilisez les options par défaut, puis cliquez sur Créer. Une fois l'instance créée, sélectionnez Ouvrir JupyterLab:

772f8868d3841ba0.png

É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 d'applications:

28dcf2790ce77c96.png

Exécutez ensuite la commande suivante pour installer la dernière version de XGBoost compatible avec Cloud AI Platform:

pip3 install xgboost==0.90

Une fois l'opération terminée, ouvrez une instance de notebook Python 3 à partir du lanceur. Vous êtes prêt à commencer dans votre notebook !

Étape 5: Importez les packages Python

Dans la première cellule de votre notebook, ajoutez les importations suivantes et exécutez la cellule. Vous pouvez l'exécuter en appuyant sur la flèche vers la droite dans le menu supérieur ou en appuyant 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

4. Télécharger et traiter les données

Nous allons utiliser un ensemble de données hypothécaire issu du site 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 à utiliser pour entraîner le modèle. Le modèle va prédire si une demande de prêt sera approuvée ou non.

Étape 1: Téléchargez l'ensemble de données prétraité

Une version de l'ensemble de données est à votre disposition dans Google Cloud Storage. Vous pouvez le 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: Lire l'ensemble de données avec Pandas

Avant de créer notre DataFrame Pandas, nous allons créer un dictionnaire 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
})

Ensuite, nous allons créer un DataFrame en lui transmettant les types de données spécifiés ci-dessus. Il est important de brasser nos données au cas où le jeu 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() permet de prévisualiser les cinq premières lignes de l'ensemble de données dans Pandas. Après avoir exécuté la cellule ci-dessus, vous devriez obtenir un résultat semblable à celui-ci:

29106b71103235a6.png

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 la prédiction. La valeur 1 indique qu'une application spécifique a été approuvée, et la valeur 0 indique 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 étiquettes, 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% du jeu de données contient des applications approuvées.

Étape 3: Créer 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 nécessite 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 utiliser la fonction get_dummies Pandas pour notre modèle XGBoost.

get_dummies prend une colonne avec plusieurs valeurs possibles et la convertit en une série de colonnes, chacune avec 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 verrez des caractéristiques uniques (comme purchaser_type sur l'image ci-dessous) réparties dans plusieurs colonnes:

83aacfaad626e538.png

Étape 4: Répartir les données en ensembles d'entraînement et de test

La répartition entraînement / test est un concept important en machine learning. Nous allons prendre la majorité de nos données et l'utiliser pour entraîner notre modèle. Nous mettons le reste de côté 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 les données:

x,y = data,labels
x_train,x_test,y_train,y_test = train_test_split(x,y)

Vous êtes maintenant prêt à créer et à entraîner votre modèle.

5. Créer, entraîner et évaluer un modèle XGBoost

Étape 1: Définissez et entraînez le modèle XGBoost

Dans XGBoost, la création d'un modèle est simple. Nous allons utiliser la classe XGBClassifier pour créer le modèle. Il nous suffit de transmettre le paramètre objective approprié 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 dans la plage (0,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 ligne de code, en appelant la méthode fit() et en lui transmettant les données d'entraînement et les étiquettes.

model.fit(x_train, y_train)

Étape 2: Évaluez la justesse 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 utiliserons ensuite la fonction accuracy_score de scikit-learn pour calculer la justesse de notre modèle en fonction de ses performances sur nos données de test. Nous lui transmettrons les valeurs de vérité terrain ainsi que les valeurs prédites par le 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 constater une justesse d'environ 87%, mais celle-ci varie légèrement, car le machine learning présente toujours une part de hasard.

Étape 3: Enregistrez votre modèle

Pour déployer le modèle, enregistrez-le dans un fichier local en exécutant le code suivant:

model.save_model('model.bst')

6. Déployer le modèle sur Cloud AI Platform

Notre modèle fonctionne en local, mais il serait utile que nous puissions faire des prédictions depuis n'importe où (pas seulement depuis 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 certaines 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 (il doit être unique) et le nom de la version de la première version de votre modèle:

# Update these to your own GCP project, model, and version names
GCP_PROJECT = 'your-gcp-project'
MODEL_BUCKET = 'gs://storage_bucket_name'
VERSION_NAME = 'v1'
MODEL_NAME = 'xgb_mortgage'

Nous sommes maintenant prêts à créer un bucket de stockage pour stocker notre fichier de modèle XGBoost. Nous indiquerons ce fichier à Cloud AI Platform lors du déploiement.

Exécutez la commande gsutil suivante depuis votre notebook pour créer un bucket:

!gsutil mb $MODEL_BUCKET

Étape 2: Copiez le fichier de modèle dans Cloud Storage

Nous allons maintenant copier notre fichier de modèle enregistré XGBoost dans Cloud Storage. Exécutez la commande gsutil suivante:

!gsutil cp ./model.bst $MODEL_BUCKET

Accédez au navigateur de stockage de votre console Cloud pour vérifier que le fichier a bien été copié:

31e2567fa0117214.png

Étape 3: Créez et déployez le modèle

Nous sommes presque prêts à déployer le modèle. La commande gcloud ai-platform suivante crée un modèle dans votre projet. Nous appellerons celui-ci xgb_mortgage:

!gcloud ai-platform models create $MODEL_NAME --region='global'

Il est maintenant temps de déployer le modèle. Pour ce faire, exécutez la commande gcloud suivante:

!gcloud ai-platform versions create $VERSION_NAME \
--model=$MODEL_NAME \
--framework='XGBOOST' \
--runtime-version=2.1 \
--origin=$MODEL_BUCKET \
--python-version=3.7 \
--project=$GCP_PROJECT \
--region='global'

Pendant l'exécution, consultez la section Modèles de la console AI Platform. La nouvelle version doit s'y déployer:

342875ba92becad1.png

Une fois le déploiement terminé, une coche verte s'affiche à l'emplacement de l'icône de chargement. Le déploiement devrait prendre deux à trois minutes.

É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 le premier exemple de notre ensemble de test:

%%writefile predictions.json
[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 le code suivant:

prediction = !gcloud ai-platform predict --model=xgb_mortgage --region='global' --json-instances=predictions.json --version=$VERSION_NAME --verbosity=none

print(prediction)

La prédiction de votre modèle doit s'afficher dans le résultat. Cet exemple particulier a été approuvé, vous devriez donc voir une valeur proche de 1.

7. Utiliser 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 à vos modèles AI Platform, vous devez lui transmettre un sous-ensemble de vos exemples de test, ainsi que les valeurs de vérité terrain correspondant à ces exemples. Créons un tableau Numpy de 500 de nos exemples de test, ainsi que leurs étiquettes de vérité terrain:

num_wit_examples = 500
test_examples = np.hstack((x_test[:num_wit_examples].values,y_test[:num_wit_examples].reshape(-1,1)))

Pour instancier l'outil de simulation What-If, il suffit de créer un objet WitConfigBuilder et de lui transmettre le modèle AI Platform que nous souhaitons analyser.

Nous utilisons ici le paramètre facultatif adjust_prediction, car l'outil de simulation What-If s'attend à une liste de scores pour chaque classe de notre modèle (dans le cas présent, n° 2). Étant donné que notre modèle ne renvoie qu'une seule valeur comprise entre 0 et 1, nous la transformons au format correct dans cette fonction:

def adjust_prediction(pred):
  return [1 - pred, pred]

config_builder = (WitConfigBuilder(test_examples.tolist(), data.columns.tolist() + ['mortgage_status'])
  .set_ai_platform_model(GCP_PROJECT, MODEL_NAME, VERSION_NAME, adjust_prediction=adjust_prediction)
  .set_target_feature('mortgage_status')
  .set_label_vocab(['denied', 'approved']))
WitWidget(config_builder, height=800)

Notez que le chargement de la visualisation prend une minute. Lors du chargement, vous devriez obtenir le résultat suivant:

4c0b00e6afcdbe01.png

L'axe des y représente la prédiction du modèle, 1 étant une prédiction approved avec un indice de confiance élevé et 0 une prédiction denied avec un indice de confiance élevé. L'axe des x est simplement l'écart 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 Datapoint Editor (Éditeur de points de données). Ici, vous pouvez cliquer sur n'importe quel point de données 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. L'application de prêt immobilier associée à ce point de données particulier provient du CFPB. Nous avons remplacé cette caractéristique par 0 et remplacé la valeur de agency_code_Department of Housing and Urban Development (HUD) par 1 pour voir ce qu'il adviendrait de la prédiction du modèle si ce prêt provenait plutôt du HUD:

717620d6a1330479.png

Comme vous pouvez le voir dans la section en bas à 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'où provient un prêt a un impact important sur les résultats du modèle, mais nous devrons procéder à davantage d'analyses pour en être sûr.

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:

60ff20ae80ed5e27.png

Étape 3: Analyse contrefactuelle

Ensuite, cliquez 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:

ae64fd7abefe5449.png

Si vous sélectionnez cette option, le point de données qui présente les valeurs de caractéristique les plus semblables à celui d'origine que vous avez sélectionné, mais qui présente la prédiction opposée, s'affiche. Vous pouvez ensuite faire défiler les valeurs des caractéristiques pour voir en quoi les deux points de données diffèrent (les différences sont surlignées 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 son ensemble, cochez la case Parties de données de dépendance et assurez-vous que l'option Graphiques de dépendance partielle globale est sélectionnée:

72117b5ceb683841.png

Ici, nous pouvons constater que les prêts provenant de HUD ont une probabilité un peu plus élevée d'être refusés. Le graphique présente cette forme, car le code agence est une caractéristique booléenne, de sorte que les valeurs ne peuvent ê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 à hauteur de 200 000 $environ. Au-delà de 200 000 $, cette caractéristique n'a aucune incidence sur la prédiction du modèle.

Étape 5: Examinez les performances globales et l'équité

Accédez ensuite à la section Performances Équité. Vous voyez ici les statistiques de performances globales 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 fonctionnalité de vérité terrain pour afficher une matrice de confusion:

fe1384ee47699498.png

Cette matrice de confusion affiche les prédictions correctes et incorrectes de notre modèle sous la forme d'un pourcentage du total. Si vous additionnez les carrés Réel Oui / Oui prévu et Non réel / Non prévu, vous obtenez la même précision que votre modèle (environ 87%).

Vous pouvez également tester le curseur du seuil, en augmentant ou en diminuant le score de classification positif que le modèle doit renvoyer avant de décider de prédire approved pour le prêt, et voir comment cela influe sur la justesse, les faux positifs et les faux négatifs. Dans ce cas, la précision est maximale autour d'un seuil de 0,55.

Ensuite, dans le menu déroulant Trancher par à gauche, sélectionnez loan_purpose_Home_purchase:

f3f1858d627d57ab.png

Vous pouvez maintenant afficher les performances pour les deux sous-ensembles de données: le "0". indique quand le prêt ne concerne pas l'achat d'une maison, et le chiffre "1" pour les cas où le prêt correspond à l'achat d'une maison. Vérifiez la justesse, le taux de faux positifs et 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% de demandes de prêt pour l'achat d'un logement et seulement pour 46% des prêts qui ne concernent pas l'achat d'un logement (les pourcentages exacts varient selon votre modèle):

318a8d5a8ffc6bea.png

Si vous sélectionnez Parité démographique à l'aide des cases d'option situées à gauche, les deux seuils seront ajustés de sorte que le modèle prédit approved pour un pourcentage similaire de candidats dans les deux segments. Quel impact cela a-t-il sur la précision, les faux positifs et les faux négatifs de chaque tranche ?

Étape 6: Explorez la distribution des fonctionnalités

Enfin, accédez à l'onglet Fonctionnalités de l'outil de simulation What-If. Cela vous indique la distribution des valeurs pour chaque caractéristique de votre ensemble de données:

48ab3c4879793324.png

Cet onglet vous permet de vérifier 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 l'Agriculture. Pour améliorer la précision du modèle, nous pouvons envisager d'ajouter davantage de prêts auprès de cette agence, si les données sont disponibles.

Nous ne proposons ici que quelques idées d'exploration de l'outil de simulation What-If. N'hésitez pas à continuer à jouer avec l'outil. Il y a beaucoup d'autres domaines à explorer !

8. Nettoyage

Si vous souhaitez continuer à utiliser cet ordinateur portable, nous vous recommandons de le désactiver lorsqu'il n'est pas utilisé. À partir de l'interface utilisateur de Notebooks dans Cloud Console, sélectionnez le notebook, puis cliquez sur Arrêter:

879147427150b6c7.png

Si vous souhaitez supprimer toutes les ressources que vous avez créées au cours de cet atelier, il vous suffit de supprimer l'instance de notebook au lieu de l'arrêter.

À l'aide du menu de navigation de Cloud Console, accédez à "Storage" (Stockage) et supprimez les deux buckets que vous avez créés pour stocker les ressources de votre modèle.