Partager via


Tutoriel : créer, évaluer et noter un modèle de prédiction d’attrition

Ce tutoriel présente un exemple de bout en bout d’un flux de travail science des données Synapse dans Microsoft Fabric. Le scénario prévoit l’élaboration d’un modèle permettant de prédire si les clients d’une banque se désabonnent ou non. Le taux d’attrition implique le taux auquel les clients bancaires terminent leur activité avec la banque.

Ce didacticiel couvre ces étapes :

  • Installer des bibliothèques personnalisées
  • Chargement des données
  • Comprendre et traiter les données par le biais d’une analyse exploratoire des données, et montrer l’utilisation de la fonction Fabric Data Wrangler
  • Utilisez scikit-learn et LightGBM pour former des modèles d’apprentissage automatique, et suivez les expériences avec les fonctionnalités MLflow et Fabric Autologging
  • Évaluer et enregistrer le modèle Machine Learning final
  • Afficher la performance du modèle avec des visualisations Power BI

Prérequis

Suivez l’évolution dans un notebook

Vous pouvez choisir l’une de ces options pour suivre l’évolution de la situation dans un notebook :

  • Ouvrez et exécutez le notebook intégré dans l’expérience Science des données
  • Chargez votre notebook à partir de GitHub vers l’expérience Science des données

Ouvrir le notebook intégré

L’exemple de notebook sur l’attrition clients accompagne ce tutoriel.

Pour ouvrir l’exemple de notebook intégré au tutoriel dans l’expérience science des données Synapse :

  1. Accédez à la page d’accueil science des données Synapse.

  2. Sélectionnez Utiliser un échantillon.

  3. Sélectionnez l’échantillon correspondant :

    • À partir de l’onglet par défaut Workflows de bout en bout (Python), si l’exemple concerne un tutoriel Python.
    • À partir de l’onglet Workflows de bout en bout (R), si l’exemple concerne un tutoriel R.
    • À partir de l’onglet Tutoriels rapides, si l’exemple concerne un tutoriel rapide.
  4. Attachez un lakehouse au notebook avant de commencer à exécuter le code.

Importer le notebook à partir de GitHub

Le notebook AIsample - Attrition clients des banques accompagne ce tutoriel.

Pour ouvrir le notebook d’accompagnement de ce tutoriel, suivez les instructions fournies dans Préparer votre système pour la science des données afin d’importer le notebook dans votre espace de travail.

Si vous préférez copier et coller le code de cette page, vous pouvez créer un nouveau notebook.

Assurez-vous d’attacher un lakehouse au notebook avant de commencer à exécuter du code.

Étape 1 : Installer des bibliothèques personnalisées

Pour le développement de modèle Machine Learning ou l’analyse de données ad hoc, vous pourriez avoir besoin d’installer rapidement une bibliothèque personnalisée pour votre session Apache Spark. Vous avez deux options d’installation des bibliothèques.

  • Utilisez les capacités d’installation en ligne (%pip ou %conda) de votre notebook pour installer une bibliothèque, dans votre notebook actuel uniquement
  • Vous pouvez également créer un environnement Fabric, installer des bibliothèques à partir de sources publiques ou y charger des bibliothèques personnalisées. Ensuite, l’administrateur de votre espace de travail peut attacher l’environnement en tant qu’environnement par défaut pour l’espace de travail. Toutes les bibliothèques de l’environnement seront ensuite disponibles pour être utilisées dans les notebooks et les définitions de travail Spark dans l’espace de travail. Pour plus d’informations sur les environnements, consultez Créer, configurer et utiliser un environnement dans Microsoft Fabric.

Pour ce tutoriel, utilisez %pip install pour installer imblearn la bibliothèque dans votre notebook.

Remarque

Le noyau PySpark redémarre après l’exécution de %pip install. Installez les bibliothèques nécessaires avant d’exécuter d’autres cellules.

# Use pip to install libraries
%pip install imblearn

Étape 2 : Chargement des données

Le jeu de données de churn.csv contient l’état d’attrition de 10 000 clients, ainsi que 14 attributs qui incluent :

  • Le score de crédit
  • L’emplacement géographique (Allemagne, France, Espagne)
  • Le sexe (homme, femme)
  • Âge
  • Ancienneté (nombre d’années où la personne était cliente à cette banque)
  • Solde du compte
  • Salaire estimé
  • Nombre de produits achetés par un client par le biais de la banque
  • État de la carte de crédit (si le client possède une carte de crédit ou non)
  • État du membre actif (que la personne soit ou non un client actif de la banque)

Le jeu de données inclut également le numéro de ligne, l’ID client et les colonnes de nom de client. Les valeurs de ces colonnes ne devraient pas influencer la décision d’un client de quitter la banque.

Un événement de clôture du compte bancaire d’un client définit le taux d’attrition pour ce client. La colonne Exited du jeu de données fait référence à l’abandon du client. Étant donné que nous disposons de peu de contexte sur ces attributs, nous n’avons pas besoin d’informations de base sur le jeu de données. Nous voulons comprendre comment ces attributs contribuent à l’état Exited.

Sur ces 10 000 clients, seuls 2 037 (environ 20 %) ont quitté la banque. En raison du taux de déséquilibre des classes, nous recommandons de générer des données synthétiques. La précision de la matrice de confusion peut ne pas avoir de pertinence pour la classification déséquilibrée. Nous pouvons mesurer la précision à l’aide de la zone sous la courbe de rappel de précision (AUPRC).

  • Ce tableau présente un aperçu des données churn.csv :
IDClient Surname CreditScore Pays Gender (Sexe) Age (Âge) Durée d’exercice Solde NumOfProducts HasCrCard IsActiveMember EstimatedSalary Ayant quitté la société
15634602 Hargrave 619 France Femme 42 2 0.00 1 1 1 101348.88 1
15647311 Hill 608 Espagne Femme 41 1 83807.86 1 0 1 112542.58 0

Télécharger le jeu de données et le charger dans le lakehouse

Définissez ces paramètres pour pouvoir utiliser ce notebook avec différents jeux de données :

IS_CUSTOM_DATA = False  # If TRUE, the dataset has to be uploaded manually

IS_SAMPLE = False  # If TRUE, use only SAMPLE_ROWS of data for training; otherwise, use all data
SAMPLE_ROWS = 5000  # If IS_SAMPLE is True, use only this number of rows for training

DATA_ROOT = "/lakehouse/default"
DATA_FOLDER = "Files/churn"  # Folder with data files
DATA_FILE = "churn.csv"  # Data file name

Ce code télécharge une version du jeu de données accessible au public, puis stocke ce jeu de données dans un lakehouse Fabric :

Important

Ajoutez un lakehouse au notebook avant de l’exécuter. Dans le cas contraire, vous obtiendrez une erreur.

import os, requests
if not IS_CUSTOM_DATA:
# With an Azure Synapse Analytics blob, this can be done in one line

# Download demo data files into the lakehouse if they don't exist
    remote_url = "https://synapseaisolutionsa.blob.core.windows.net/public/bankcustomerchurn"
    file_list = ["churn.csv"]
    download_path = "/lakehouse/default/Files/churn/raw"

    if not os.path.exists("/lakehouse/default"):
        raise FileNotFoundError(
            "Default lakehouse not found, please add a lakehouse and restart the session."
        )
    os.makedirs(download_path, exist_ok=True)
    for fname in file_list:
        if not os.path.exists(f"{download_path}/{fname}"):
            r = requests.get(f"{remote_url}/{fname}", timeout=30)
            with open(f"{download_path}/{fname}", "wb") as f:
                f.write(r.content)
    print("Downloaded demo data files into lakehouse.")

Commencez à enregistrer le temps nécessaire à l’exécution du notebook :

# Record the notebook running time
import time

ts = time.time()

Lire des données brutes à partir du lakehouse

Ce code lit les données brutes de la section Fichiers du lakehouse, et ajoute des colonnes supplémentaires pour les différentes parties de la date. La création de la table delta partitionnée utilise ces informations.

df = (
    spark.read.option("header", True)
    .option("inferSchema", True)
    .csv("Files/churn/raw/churn.csv")
    .cache()
)

Créer un DataFrame Pandas à partir du jeu de données

Ce code convertit le DataFrame spark en DataFrame pandas pour faciliter le traitement et la visualisation :

df = df.toPandas()

Étape 3 : Effectuer une analyse exploratoire des données

Afficher les données brutes

Explorez les données brutes avec display, calculez des statistiques de base et affichez des graphiques. Vous devez d’abord importer les bibliothèques requises pour la visualisation des données , par exemple, seaborn. Seaborn est une bibliothèque de visualisation des données Python, qui fournit une interface de haut niveau pour construire des visuels sur des cadres de données et des tableaux.

import seaborn as sns
sns.set_theme(style="whitegrid", palette="tab10", rc = {'figure.figsize':(9,6)})
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib import rc, rcParams
import numpy as np
import pandas as pd
import itertools
display(df, summary=True)

Utiliser Data Wrangler pour effectuer le nettoyage initial des données

Lancez Data Wrangler directement depuis le notebook pour explorer et transformer les dataframes pandas. Dans l’onglet Données du ruban notebook, utilisez l’invite déroulante Data Wrangler pour parcourir les DataFrames pandas activées disponibles pour l’édition. Sélectionnez le DataFrame que vous souhaitez ouvrir dans Data Wrangler.

Remarque

Data Wrangler ne peut pas être ouvert si le noyau du notebook est occupé. L’exécution de cellule doit se terminer avant de lancer Data Wrangler. En savoir plus sur Data Wrangler.

Screenshot that shows where to access Data Wrangler.

Après le lancement de Data Wrangler, une vue d’ensemble descriptive du panneau de données est généré, comme le montrent les images suivantes. La vue d’ensemble comprend des informations sur la dimension du DataFrame, les valeurs manquantes, etc. Vous pouvez utiliser Data Wrangler pour générer le script permettant de supprimer les lignes avec des valeurs manquantes, les lignes dupliquées et les colonnes avec des noms spécifiques. Vous pouvez ensuite copier le script dans une cellule. La cellule suivante montre ce script copié.

Screenshot that shows the Data Wrangler menu.

Screenshot that shows missing data in Data Wrangler.

def clean_data(df):
    # Drop rows with missing data across all columns
    df.dropna(inplace=True)
    # Drop duplicate rows in columns: 'RowNumber', 'CustomerId'
    df.drop_duplicates(subset=['RowNumber', 'CustomerId'], inplace=True)
    # Drop columns: 'RowNumber', 'CustomerId', 'Surname'
    df.drop(columns=['RowNumber', 'CustomerId', 'Surname'], inplace=True)
    return df

df_clean = clean_data(df.copy())

Déterminer les attributs

Ce code détermine les attributs catégoriels, numériques et cibles :

# Determine the dependent (target) attribute
dependent_variable_name = "Exited"
print(dependent_variable_name)
# Determine the categorical attributes
categorical_variables = [col for col in df_clean.columns if col in "O"
                        or df_clean[col].nunique() <=5
                        and col not in "Exited"]
print(categorical_variables)
# Determine the numerical attributes
numeric_variables = [col for col in df_clean.columns if df_clean[col].dtype != "object"
                        and df_clean[col].nunique() >5]
print(numeric_variables)

Affichez le résumé en cinq chiffres

Utiliser des tracés de zone pour afficher le résumé à cinq nombres

  • le score minimum
  • premier quartile
  • médiane
  • troisième quartile
  • score maximal

pour les attributs numériques.

df_num_cols = df_clean[numeric_variables]
sns.set(font_scale = 0.7) 
fig, axes = plt.subplots(nrows = 2, ncols = 3, gridspec_kw =  dict(hspace=0.3), figsize = (17,8))
fig.tight_layout()
for ax,col in zip(axes.flatten(), df_num_cols.columns):
    sns.boxplot(x = df_num_cols[col], color='green', ax = ax)
# fig.suptitle('visualize and compare the distribution and central tendency of numerical attributes', color = 'k', fontsize = 12)
fig.delaxes(axes[1,2])

Screenshot that shows a notebook display of the box plot for numerical attributes.

Afficher la répartition des clients sortis et non sortis

Afficher la distribution des clients sortants et non sortants entre les attributs catégoriels :

attr_list = ['Geography', 'Gender', 'HasCrCard', 'IsActiveMember', 'NumOfProducts', 'Tenure']
fig, axarr = plt.subplots(2, 3, figsize=(15, 4))
for ind, item in enumerate (attr_list):
    sns.countplot(x = item, hue = 'Exited', data = df_clean, ax = axarr[ind%2][ind//2])
fig.subplots_adjust(hspace=0.7)

Screenshot that shows a notebook display of the distribution of exited versus non-exited customers.

Afficher la distribution d’attributs numériques

Utilisez un histogramme pour montrer la distribution de fréquence des attributs numériques :

columns = df_num_cols.columns[: len(df_num_cols.columns)]
fig = plt.figure()
fig.set_size_inches(18, 8)
length = len(columns)
for i,j in itertools.zip_longest(columns, range(length)):
    plt.subplot((length // 2), 3, j+1)
    plt.subplots_adjust(wspace = 0.2, hspace = 0.5)
    df_num_cols[i].hist(bins = 20, edgecolor = 'black')
    plt.title(i)
# fig = fig.suptitle('distribution of numerical attributes', color = 'r' ,fontsize = 14)
plt.show()

Screenshot that shows a notebook display of numerical attributes.

Effectuer l’ingénierie de caractéristiques

Cette ingénierie de caractéristiques génère de nouveaux attributs basés sur les attributs actuels :

df_clean["NewTenure"] = df_clean["Tenure"]/df_clean["Age"]
df_clean["NewCreditsScore"] = pd.qcut(df_clean['CreditScore'], 6, labels = [1, 2, 3, 4, 5, 6])
df_clean["NewAgeScore"] = pd.qcut(df_clean['Age'], 8, labels = [1, 2, 3, 4, 5, 6, 7, 8])
df_clean["NewBalanceScore"] = pd.qcut(df_clean['Balance'].rank(method="first"), 5, labels = [1, 2, 3, 4, 5])
df_clean["NewEstSalaryScore"] = pd.qcut(df_clean['EstimatedSalary'], 10, labels = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])

Utiliser Data Wrangler pour effectuer un encodage à chaud

En suivant les mêmes étapes que celles décrites précédemment pour lancer Data Wrangler, utilisez Data Wrangler pour effectuer un encodage en une seule fois. Cette cellule montre le script généré copié pour l’encodage à une touche :

Screenshot that shows one-hot encoding in Data Wrangler.

Screenshot that shows the selection of columns in Data Wrangler.

df_clean = pd.get_dummies(df_clean, columns=['Geography', 'Gender'])

Créer une table delta pour générer le rapport Power BI

table_name = "df_clean"
# Create a PySpark DataFrame from pandas
sparkDF=spark.createDataFrame(df_clean) 
sparkDF.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Résumé des observations de l’analyse exploratoire des données

  • La plupart des clients sont de France. L’Espagne a le taux d’attrition le plus bas, comparé à la France et à l’Allemagne.
  • La plupart des clients ont des cartes de crédit
  • Certains clients ont plus de 60 ans et ont des scores de crédit inférieurs à 400. Toutefois, ils ne peuvent pas être considérés comme des valeurs hors norme
  • Très peu de clients ont plus de deux produits bancaires
  • Les clients inactifs ont un taux d’attrition plus élevé
  • L’ancienneté et le sexe ont peu d’impact sur la décision d’un client de fermer un compte bancaire

Étape 4 : assurer la formation et le suivi du modèle

Les données étant en place, vous pouvez maintenant définir le modèle. Appliquez les modèles de forêt aléatoire et de LightGBM dans ce notebook.

Utilisez les bibliothèques scikit-learn et LightGBM pour implémenter les modèles, avec quelques lignes de code. En outre, utilisez MLflow et Fabric Autologging pour suivre les expériences.

Cet exemple de code charge la table delta à partir du lakehouse. Vous pouvez utiliser d’autres tables delta qui utilisent elles-mêmes le lakehouse comme source.

SEED = 12345
df_clean = spark.read.format("delta").load("Tables/df_clean").toPandas()

Générer une expérience pour le suivi et l’enregistrement des modèles en utilisant MLflow

Cette section montre comment générer une expérience et spécifie les paramètres de modèle et d’entraînement et les métriques de scoring. En outre, il montre comment entraîner les modèles, les journaliser et enregistrer les modèles entraînés pour une utilisation ultérieure.

import mlflow

# Set up the experiment name
EXPERIMENT_NAME = "sample-bank-churn-experiment"  # MLflow experiment name

Autologging capture automatiquement les valeurs des paramètres d’entrée et les métriques de sortie d’un modèle Machine Learning, au fur et à mesure de l’apprentissage de ce modèle. Ces informations sont ensuite enregistrées dans votre espace de travail, où les API MLflow ou l’expérience correspondante dans votre espace de travail peuvent y accéder et les visualiser.

Une fois terminée, votre expérience ressemble à cette image :

Screenshot that shows the experiment page for the bank churn experiment.

Toutes les expériences, avec leurs noms respectifs, sont enregistrées et vous pouvez suivre leurs paramètres et leurs métriques. Pour en savoir plus sur l’autologging, consultez Autologging dans Microsoft Fabric.

Définir des spécifications d’expérience et d’autologging

mlflow.set_experiment(EXPERIMENT_NAME) # Use a date stamp to append to the experiment
mlflow.autolog(exclusive=False)

Importer scikit-learn et LightGBM

# Import the required libraries for model training
from sklearn.model_selection import train_test_split
from lightgbm import LGBMClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, f1_score, precision_score, confusion_matrix, recall_score, roc_auc_score, classification_report

Préparation de jeux de données d’apprentissage et de test

y = df_clean["Exited"]
X = df_clean.drop("Exited",axis=1)
# Train/test separation
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=SEED)

Appliquons la technique SMOTE aux données d’apprentissage

La classification déséquilibrée pose un problème, car elle comporte trop peu d’exemples de la classe minoritaire pour qu’un modèle puisse apprendre efficacement la délimitation de décision. Pour y remédier, la technique de suréchantillonnage synthétique des minorités (SMOTE) est la plus utilisée pour synthétiser de nouveaux échantillons pour la classe minoritaire. Accédez à SMOTE à l’aide de la bibliothèque imblearn que vous avez installée à l’étape 1.

Appliquons SMOTE uniquement aux données d’apprentissage. Vous devez laisser le jeu de données de test dans sa distribution déséquilibrée d’origine, afin d’obtenir une approximation valide de la performance du modèle sur les données d’origine. Cette expérience représente la situation en production.

from collections import Counter
from imblearn.over_sampling import SMOTE

sm = SMOTE(random_state=SEED)
X_res, y_res = sm.fit_resample(X_train, y_train)
new_train = pd.concat([X_res, y_res], axis=1)

Pour plus d’informations, consultez SMOTE et Du suréchantillonnage aléatoire à SMOTE et ADASYN. Le site web d’apprentissage déséquilibré héberge ces ressources.

Formation du modèle

Utilisez Random Forest pour former le modèle, avec une profondeur maximale de quatre, et avec quatre caractéristiques :

mlflow.sklearn.autolog(registered_model_name='rfc1_sm')  # Register the trained model with autologging
rfc1_sm = RandomForestClassifier(max_depth=4, max_features=4, min_samples_split=3, random_state=1) # Pass hyperparameters
with mlflow.start_run(run_name="rfc1_sm") as run:
    rfc1_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    print("run_id: {}; status: {}".format(rfc1_sm_run_id, run.info.status))
    # rfc1.fit(X_train,y_train) # Imbalanced training data
    rfc1_sm.fit(X_res, y_res.ravel()) # Balanced training data
    rfc1_sm.score(X_test, y_test)
    y_pred = rfc1_sm.predict(X_test)
    cr_rfc1_sm = classification_report(y_test, y_pred)
    cm_rfc1_sm = confusion_matrix(y_test, y_pred)
    roc_auc_rfc1_sm = roc_auc_score(y_res, rfc1_sm.predict_proba(X_res)[:, 1])

Utilisez Random Forest pour former le modèle, avec une profondeur maximale de huit et six caractéristiques :

mlflow.sklearn.autolog(registered_model_name='rfc2_sm')  # Register the trained model with autologging
rfc2_sm = RandomForestClassifier(max_depth=8, max_features=6, min_samples_split=3, random_state=1) # Pass hyperparameters
with mlflow.start_run(run_name="rfc2_sm") as run:
    rfc2_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    print("run_id: {}; status: {}".format(rfc2_sm_run_id, run.info.status))
    # rfc2.fit(X_train,y_train) # Imbalanced training data
    rfc2_sm.fit(X_res, y_res.ravel()) # Balanced training data
    rfc2_sm.score(X_test, y_test)
    y_pred = rfc2_sm.predict(X_test)
    cr_rfc2_sm = classification_report(y_test, y_pred)
    cm_rfc2_sm = confusion_matrix(y_test, y_pred)
    roc_auc_rfc2_sm = roc_auc_score(y_res, rfc2_sm.predict_proba(X_res)[:, 1])

Formez le modèle avec LightGBM :

# lgbm_model
mlflow.lightgbm.autolog(registered_model_name='lgbm_sm')  # Register the trained model with autologging
lgbm_sm_model = LGBMClassifier(learning_rate = 0.07, 
                        max_delta_step = 2, 
                        n_estimators = 100,
                        max_depth = 10, 
                        eval_metric = "logloss", 
                        objective='binary', 
                        random_state=42)

with mlflow.start_run(run_name="lgbm_sm") as run:
    lgbm1_sm_run_id = run.info.run_id # Capture run_id for model prediction later
    # lgbm_sm_model.fit(X_train,y_train) # Imbalanced training data
    lgbm_sm_model.fit(X_res, y_res.ravel()) # Balanced training data
    y_pred = lgbm_sm_model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    cr_lgbm_sm = classification_report(y_test, y_pred)
    cm_lgbm_sm = confusion_matrix(y_test, y_pred)
    roc_auc_lgbm_sm = roc_auc_score(y_res, lgbm_sm_model.predict_proba(X_res)[:, 1])

Visualisez l’artefact de l’expérience pour suivre les performances du modèle

Les expériences sont automatiquement sauvegardées dans l’artefact d’expérience. Vous pouvez trouver cet artefact dans l’espace de travail. Un nom d’artefact est basé sur le nom utilisé pour définir l’expérience. Tous les modèles formés, leurs exécutions, les mesures de performance et les paramètres du modèle sont enregistrés sur la page d’expérience.

Pour afficher vos expériences :

  1. Dans le volet gauche, sélectionnez votre espace de travail.
  2. Recherchez et sélectionnez le nom de l’expérience, dans ce cas sample-bank-churn-experiment.

Screenshot that shows logged values for one of the models.

Étape 5 : Évaluer et enregistrer le modèle Machine Learning final

Ouvrez l’expérience enregistrée à partir de l’espace de travail pour sélectionner et enregistrer le meilleur modèle :

# Define run_uri to fetch the model
# MLflow client: mlflow.model.url, list model
load_model_rfc1_sm = mlflow.sklearn.load_model(f"runs:/{rfc1_sm_run_id}/model")
load_model_rfc2_sm = mlflow.sklearn.load_model(f"runs:/{rfc2_sm_run_id}/model")
load_model_lgbm1_sm = mlflow.lightgbm.load_model(f"runs:/{lgbm1_sm_run_id}/model")

Évaluer les performances des modèles enregistrés sur le jeu de données de test

ypred_rfc1_sm = load_model_rfc1_sm.predict(X_test) # Random forest with maximum depth of 4 and 4 features
ypred_rfc2_sm = load_model_rfc2_sm.predict(X_test) # Random forest with maximum depth of 8 and 6 features
ypred_lgbm1_sm = load_model_lgbm1_sm.predict(X_test) # LightGBM

Afficher les vrais/faux positifs/négatifs à l’aide d’une matrice de confusion

Pour évaluer la précision de la classification, créez un script qui trace la matrice de confusion. Vous pouvez également tracer une matrice de confusion à l’aide des outils SynapseML, comme le montre l’exemple de détection de la fraude.

def plot_confusion_matrix(cm, classes,
                          normalize=False,
                          title='Confusion matrix',
                          cmap=plt.cm.Blues):
    print(cm)
    plt.figure(figsize=(4,4))
    plt.rcParams.update({'font.size': 10})
    plt.imshow(cm, interpolation='nearest', cmap=cmap)
    plt.title(title)
    plt.colorbar()
    tick_marks = np.arange(len(classes))
    plt.xticks(tick_marks, classes, rotation=45, color="blue")
    plt.yticks(tick_marks, classes, color="blue")

    fmt = '.2f' if normalize else 'd'
    thresh = cm.max() / 2.
    for i, j in itertools.product(range(cm.shape[0]), range(cm.shape[1])):
        plt.text(j, i, format(cm[i, j], fmt),
                 horizontalalignment="center",
                 color="red" if cm[i, j] > thresh else "black")

    plt.tight_layout()
    plt.ylabel('True label')
    plt.xlabel('Predicted label')

Créez une matrice de confusion pour le classifieur de la forêt aléatoire, avec une profondeur maximale de quatre, avec quatre caractéristiques :

cfm = confusion_matrix(y_test, y_pred=ypred_rfc1_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='Random Forest with max depth of 4')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for random forest with a maximum depth of four.

Créez une matrice de confusion pour le classifieur de la forêt aléatoire avec une profondeur maximale de huit, avec six caractéristiques :

cfm = confusion_matrix(y_test, y_pred=ypred_rfc2_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='Random Forest with max depth of 8')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for random forest with a maximum depth of eight.

Créer une matrice de confusion pour LightGBM :

cfm = confusion_matrix(y_test, y_pred=ypred_lgbm1_sm)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
                      title='LightGBM')
tn, fp, fn, tp = cfm.ravel()

Screenshot that shows a notebook display of a confusion matrix for LightGBM.

Enregistrer les résultats pour Power BI

Enregistrez l’image delta dans le lakehouse, pour déplacer les résultats de la prédiction du modèle vers une visualisation Power BI.

df_pred = X_test.copy()
df_pred['y_test'] = y_test
df_pred['ypred_rfc1_sm'] = ypred_rfc1_sm
df_pred['ypred_rfc2_sm'] =ypred_rfc2_sm
df_pred['ypred_lgbm1_sm'] = ypred_lgbm1_sm
table_name = "df_pred_results"
sparkDF=spark.createDataFrame(df_pred)
sparkDF.write.mode("overwrite").format("delta").option("overwriteSchema", "true").save(f"Tables/{table_name}")
print(f"Spark DataFrame saved to delta table: {table_name}")

Étape 6 : accéder aux visualisations dans Power BI

Accédez à votre table enregistrée dans Power BI :

  1. Sur la gauche, sélectionnez Hub de données OneLake
  2. Sélectionnez le lakehouse que vous avez ajouté à ce notebook
  3. Dans la section Ouvrir ce Lakehouse, sélectionnez Ouvrir
  4. Sur le ruban, sélectionnez Nouveau modèle sémantique. Sélectionnez df_pred_results, puis sélectionnez Continuer pour créer un nouveau modèle sémantique Power BI lié aux prédictions
  5. Sélectionnez Nouveau rapport dans les outils situés en haut de la page des modèles sémantiques, pour ouvrir la page de création de rapports Power BI

La capture d’écran suivante montre quelques exemples de visualisations. Le volet de données affiche les tables delta et les colonnes à sélectionner dans une table. Après avoir sélectionné la catégorie (x) et l’axe des valeurs (y) appropriés, vous pouvez choisir les filtres et les fonctions - par exemple, la somme ou la moyenne de la colonne du tableau.

Remarque

Dans cette capture d’écran, l’exemple illustré décrit l’analyse des résultats de prédiction enregistrés dans Power BI :

Screenshot that shows a Power BI dashboard example.

Toutefois, pour un cas d’utilisation réel d’attrition clients, l’utilisateur pourrait avoir besoin d’un ensemble plus complet d’exigences concernant les visualisations à créer, sur la base d’une expertise en la matière et de ce que l’entreprise et l’équipe d’analyse marketing ont normalisé en tant que métriques.

Le rapport Power BI montre que les clients qui utilisent plus de deux des produits bancaires ont un taux d’attrition plus élevé. Toutefois, peu de clients avaient plus de deux produits. (Voir le graphique dans le volet en bas à gauche.) La banque devrait collecter davantage de données, mais aussi étudier d’autres caractéristiques en corrélation avec un plus grand nombre de produits.

Les clients bancaires en Allemagne ont un taux d’attrition plus élevé par rapport aux clients en France et en Espagne. (Voir le tracé dans le panneau inférieur droit). En fonction des résultats du rapport, un examen sur les facteurs qui ont encouragé les clients à quitter peut aider.

Les clients d’âge moyen (entre 25 et 45 ans) sont plus nombreux. Les clients âgés de 45 à 60 ans ont tendance à quitter plus.

Enfin, les clients dont la cote de crédit est plus faible quitteront très probablement la banque pour d’autres institutions financières. La banque devrait étudier les moyens d’encourager les clients dont les scores de crédit et les soldes de compte sont moins élevés à rester dans la banque.

# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")