Esercitazione: Creare, valutare e assegnare un punteggio a un modello di previsione dell’abbandono
Questa esercitazione presenta un esempio end-to-end di un flusso di lavoro di data science Synapse in Microsoft Fabric. Lo scenario crea un modello per prevedere se i clienti di una banca abbandonano. Il tasso di abbandono, o tasso di attrito, rappresenta il tasso a cui i clienti di una banca terminano il loro rapporto con la banca.
Questa esercitazione comprende i seguenti passaggi:
- Installare librerie personalizzate
- Caricare i dati
- Comprendere ed elaborare i dati tramite l'analisi esplorativa dei dati e mostrare l'uso della funzionalità Data Wrangler di Fabric
- Usare scikit-learn e LightGBM per eseguire il training di modelli di apprendimento automatico e tenere traccia degli esperimenti con le funzionalità di registrazione automatica di Fabric e MLflow
- Valutare e salvare il modello di apprendimento automatico finale
- Visualizzare le prestazioni del modello con le visualizzazioni di Power BI
Prerequisiti
Ottenere una sottoscrizione di Microsoft Fabric. In alternativa, iscriversi per ottenere una versione di valutazione di Microsoft Fabric gratuita.
Accedere a Microsoft Fabric.
Usare l’opzione esperienza sul lato sinistro della home page per passare all'esperienza Science di Synapse.
- Se necessario, creare un lakehouse di Microsoft Fabric come descritto in Creare un lakehouse in Microsoft Fabric.
Seguire la procedura in un notebook
È possibile scegliere una di queste opzioni per seguire la procedura in un notebook:
- Aprire ed eseguire il notebook predefinito nell'esperienza Data Science
- Caricare il notebook da GitHub nell'esperienza Data Science
Aprire il notebook predefinito
Il notebook di abbandono dei clienti di esempio accompagna questa esercitazione.
Per aprire il notebook di esempio predefinito dell'esercitazione nell'esperienza Synapse Data Science:
Passare alla home page di Synapse Data Science.
Selezionare Usa un esempio.
Selezionare l’esempio corrispondente:
- Dalla scheda predefinita Flussi di lavoro end-to-end (Python), se l'esempio è relativo a un'esercitazione su Python.
- Dalla scheda Flussi di lavoro end-to-end (R), se l'esempio è relativo a un'esercitazione su R.
- Dalla scheda Esercitazioni rapide, se l'esempio è relativo a un'esercitazione rapida.
Collegare un lakehouse al notebook prima di iniziare a eseguire il codice.
Importare il notebook da GitHub
Il notebook AIsample - Bank Customer Churn.ipynb accompagna questa esercitazione.
Per aprire il notebook di accompagnamento per questa esercitazione, seguire le istruzioni riportate in Preparare il sistema per le esercitazioni di data science per importare il notebook nell'area di lavoro.
Se si preferisce copiare e incollare il codice da questa pagina, è possibile creare un nuovo notebook.
Assicurarsi di collegare un lakehouse al notebook prima di iniziare a eseguire il codice.
Passaggio 1: installare librerie personalizzate
Per lo sviluppo di modelli di apprendimento automatico o l'analisi dei dati ad hoc, potrebbe essere necessario installare rapidamente una libreria personalizzata per la sessione di Apache Spark. Sono disponibili due opzioni per installare le librerie.
- Usare le funzionalità di installazione inline (
%pip
o%conda
) del notebook per installare una libreria solo nel notebook corrente. - In alternativa, è possibile creare un ambiente Fabric, installare librerie da origini pubbliche o caricarvi librerie personalizzate e quindi l'amministratore dell'area di lavoro può collegare l'ambiente come predefinito per l'area di lavoro. Tutte le librerie nell'ambiente diventano quindi disponibili per l'uso in qualsiasi notebook e definizione del processo Spark nell'area di lavoro. Per altre informazioni sugli ambienti, vedere creare, configurare e usare un ambiente in Microsoft Fabric.
Per questa esercitazione, usare %pip install
per installare la libreria imblearn
nel notebook.
Nota
Il kernel PySpark viene riavviato dopo l'esecuzione di %pip install
. Installare le librerie necessarie prima di eseguire qualsiasi altra cella.
# Use pip to install libraries
%pip install imblearn
Passaggio 2: caricare i dati
Il set di dati in churn.csv contiene lo stato di abbandono di 10.000 clienti, insieme a 14 attributi che includono:
- Punteggio sul credito
- Posizione geografica (Germania, Francia, Spagna)
- Sesso (maschio, femmina)
- Età
- Anzianità (numero di anni in cui la persona è stata cliente in quella banca)
- Saldo del conto
- Stipendio stimato
- Numero di prodotti acquistati da un cliente tramite la banca
- Stato della carta di credito (se un cliente ha o meno una carta di credito)
- Stato membro attivo (se la persona è un cliente della banca attivo o meno)
Il set di dati include anche le colonne numero di riga, ID cliente e cognome del cliente. I valori in queste colonne non devono influenzare la decisione di un cliente di lasciare la banca.
Un evento di chiusura del conto bancario del cliente definisce l’abbandono per il cliente. La colonna del set di dati Exited
si riferisce all'abbandono del cliente. Dato che questi attributi hanno poco contesto, non sono necessarie informazioni di base sul set di dati. Si vuole comprendere come questi attributi contribuiscono allo stato Exited
.
Su questi 10.000 clienti, solo 2037 clienti (circa il 20%) ha lasciato la banca. A causa del rapporto di squilibrio tra classi, è consigliabile generare dati sintetici. L'accuratezza della matrice di confusione potrebbe non avere rilevanza per la classificazione sbilanciata. È possibile misurare l'accuratezza usando l'area sotto la curva di richiamo di precisione (AUPRC).
- Questa tabella mostra un’anteprima dei dati
churn.csv
:
CustomerID | Cognome | CreditScore | Geografia | Genere | Età | Anzianità | Saldo | NumOfProducts | HasCrCard | IsActiveMember | EstimatedSalary | Usciti |
---|---|---|---|---|---|---|---|---|---|---|---|---|
15634602 | Hargrave | 619 | Francia | Femmina | 42 | 2 | 0.00 | 1 | 1 | 1 | 101348,88 | 1 |
15647311 | Hill | 608 | Spagna | Femmina | 41 | 1 | 83807,86 | 1 | 0 | 1 | 112542,58 | 0 |
Scaricare il set di dati e caricarlo nel lakehouse
Definire questi parametri, in modo da poter usare questo notebook con set di dati diversi:
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
Questo codice scarica una versione disponibile pubblicamente del set di dati, quindi la archivia in un lakehouse di Fabric:
Importante
Aggiungere un lakehouse al notebook prima di eseguirlo. In caso contrario, verrà generato un errore.
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.")
Avviare la registrazione del tempo necessario per eseguire il notebook:
# Record the notebook running time
import time
ts = time.time()
Leggere i dati non elaborati dal lakehouse
Questo codice legge i dati non elaborati dalla sezione Files e aggiunge altre colonne per parti di data diverse. La creazione della tabella delta partizionata usa queste informazioni.
df = (
spark.read.option("header", True)
.option("inferSchema", True)
.csv("Files/churn/raw/churn.csv")
.cache()
)
Creare un DataFrame Pandas da un set di dati
Questo codice converte il dataframe Spark in un dataframe Pandas, per semplificare l'elaborazione e la visualizzazione:
df = df.toPandas()
Passaggio 3: eseguire l'analisi esplorativa dei dati
Visualizzazione di dati non elaborati
Esplorare i dati non elaborati con display
, calcolare alcune statistiche di base e mostrare le visualizzazioni del grafico. È prima necessario importare le librerie necessarie per la visualizzazione dei dati, ad esempio seaborn. Seaborn è una libreria di visualizzazioni dei dati Python che offre un'interfaccia di livello generale per creare oggetti visivi su DataFrame e matrici.
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)
Usare Data Wrangler per eseguire la pulizia iniziale dei dati
Avviare Data Wrangler direttamente dal notebook per esplorare e trasformare i dataframe Pandas. Nella scheda Dati della barra multifunzione del notebook usare il prompt a discesa Data Wrangler per esplorare i DataFrame Pandas attivati disponibili per la modifica. Selezionare il DataFrame da aprire in Data Wrangler.
Nota
Data Wrangler non può essere aperto mentre il kernel del notebook è occupato. L'esecuzione della cella deve terminare prima di avviare Data Wrangler. Altre informazioni su Data Wrangler.
Dopo l'avvio di Data Wrangler, viene generata una panoramica descrittiva del pannello dati, come illustrato nelle immagini seguenti. La panoramica include informazioni sulla dimensione del DataFrame, sugli eventuali valori mancanti e così via. È possibile usare Data Wrangler per generare lo script per eliminare le righe con valori mancanti, le righe duplicate e le colonne con nomi specifici. È quindi possibile copiare lo script in una cella. La cella successiva mostra lo script copiato.
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())
Determinazione degli attributi
Questo codice determina gli attributi categorici, numerici e di destinazione:
# 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)
Visualizzare il riepilogo in cinque numeri
Usare i box plot per visualizzare il riepilogo in cinque numeri
- il punteggio minimo
- primo quartile
- mediana
- terzo quartile
- punteggio massimo
per gli attributi numerici.
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])
Visualizzare la distribuzione dei clienti usciti e non usciti
Visualizzare la distribuzione dei clienti usciti rispetto ai clienti non usciti, tra gli attributi categorici:
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)
Visualizzare la distribuzione degli attributi numerici
Usare un istogramma per visualizzare la distribuzione della frequenza degli attributi numerici:
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()
Eseguire l'ingegneria delle funzionalità
Questa ingegneria delle funzionalità genera nuovi attributi in base agli attributi correnti:
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])
Usare Data Wrangler per eseguire la codifica one-hot
Con gli stessi passaggi per avviare Data Wrangler, come illustrato in precedenza, usare Data Wrangler per eseguire la codifica one-hot. Questa cella mostra lo script generato copiato per la codifica one-hot:
df_clean = pd.get_dummies(df_clean, columns=['Geography', 'Gender'])
Creare una tabella differenziale per generare il report di 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}")
Riepilogo delle osservazioni dell'analisi esplorativa dei dati
- La maggior parte dei clienti proviene dalla Francia. La Spagna ha il tasso di abbandono più basso, rispetto alla Francia e alla Germania.
- La maggior parte dei clienti ha carte di credito
- Alcuni clienti superano i 60 anni di età e hanno punteggi di credito inferiori a 400. Tuttavia, non possono essere considerati come outlier
- Pochissimi clienti hanno più di due prodotti bancari
- I clienti inattivi hanno un tasso di abbandono più elevato
- Il sesso e gli anni di anzianità hanno un impatto minimo sulla decisione di un cliente di chiudere un conto bancario
Passaggio 4: eseguire il training e il rilevamento del modello
Con i dati disponibili, è ora possibile definire il modello. Applicare modelli casuali di foresta e LightGBM in questo notebook.
Usare le librerie scikit-learn e LightGBM per implementare i modelli, con alcune righe di codice. Usare inoltre MLfLow e la registrazione automatica di Fabric per tenere traccia degli esperimenti.
Questo esempio di codice carica la tabella differenziale dal lakehouse. È possibile usare altre tabelle delta che, a loro volta, usano il lakehouse come origine.
SEED = 12345
df_clean = spark.read.format("delta").load("Tables/df_clean").toPandas()
Generare un esperimento per monitorare e registrare i modelli usando MLflow
Questa sezione illustra come generare un esperimento e specifica i parametri del modello e del training, nonché le metriche di assegnazione dei punteggi. Illustra inoltre come eseguire il training dei modelli, registrarli e salvare i modelli sottoposti a training per usarli in un secondo momento.
import mlflow
# Set up the experiment name
EXPERIMENT_NAME = "sample-bank-churn-experiment" # MLflow experiment name
L'assegnazione automatica acquisisce automaticamente sia i valori dei parametri di input che le metriche di output di un modello di apprendimento automatico, in quanto viene eseguito il training del modello. Queste informazioni vengono quindi registrate nell'area di lavoro, da cui le API MLflow o l'esperimento corrispondente nell'area di lavoro possono accedervi e visualizzarle.
Al termine, l'esperimento sarà simile all'immagine seguente:
Tutti gli esperimenti con i rispettivi nomi vengono registrati ed è possibile tenere traccia dei parametri e delle metriche delle prestazioni. Per altre informazioni sulla registrazione automatica, vedere l'articolo Registrazione automatica in Microsoft Fabric.
Impostare le specifiche dell'esperimento e della registrazione automatica
mlflow.set_experiment(EXPERIMENT_NAME) # Use a date stamp to append to the experiment
mlflow.autolog(exclusive=False)
Importare scikit-learn e 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
Preparare i set di dati di training e di 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)
Applicare SMOTE ai dati di training
La classificazione sbilanciata presenta un problema, poiché contiene troppi esempi della classe di minoranza per un modello per apprendere efficacemente il limite decisionale. Per gestire questo problema, Synthetic Minority Oversampling Technique (SMOTE) è la tecnica più usata per sintetizzare nuovi campioni per la classe di minoranza. Accedere a SMOTE con la libreria imblearn
installata nel passaggio 1.
Applicare SMOTE solo al set di dati di training. È necessario lasciare il set di dati di test nella distribuzione originale sbilanciata per ottenere un'approssimazione valida delle prestazioni del modello sui dati originali. Questo esperimento rappresenta la situazione in produzione.
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)
Per altre informazioni, vedere SMOTE e Dal sovracampionamento casuale a SMOTE e ADASYN. Il sito Web con apprendimento sbilanciato ospita queste risorse.
Eseguire il training del modello
Usare la foresta casuale per eseguire il training del modello, con una profondità massima di quattro e con quattro funzionalità:
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])
Usare la foresta casuale per eseguire il training del modello, con una profondità massima di otto e con sei funzionalità:
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])
Eseguire il training del modello con 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])
Visualizzare l'artefatto dell'esperimento per tenere traccia delle prestazioni del modello
Le esecuzioni dell'esperimento vengono salvate automaticamente nell'artefatto dell'esperimento. È possibile trovare l'artefatto nell'area di lavoro. Un nome di artefatto si basa sul nome usato per impostare l'esperimento. Tutti i modelli sottoposti a training, le esecuzioni, le metriche delle prestazioni e i parametri del modello vengono registrati nella pagina dell'esperimento.
Per visualizzare gli esperimenti:
- Nel pannello a sinistra, selezionare l'area di lavoro.
- Trovare e selezionare il nome dell'esperimento, in questo caso sample-bank-churn-experiment.
Passaggio 5: valutare e salvare il modello di apprendimento automatico finale
Aprire l'esperimento salvato dall'area di lavoro per selezionare e salvare il modello migliore:
# 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")
Valutare le prestazioni dei modelli salvati nel set di dati di 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
Mostrare veri/falsi positivi/negativi usando una matrice di confusione
Per valutare l'accuratezza della classificazione, compilare uno script che traccia la matrice di confusione. È anche possibile tracciare una matrice di confusione usando gli strumenti SynapseML, come illustrato nell'esempio di rilevamento delle frodi.
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')
Creare una matrice di confusione per il classificatore di foresta casuale, con una profondità massima di quattro, con quattro funzionalità:
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()
Creare una matrice di confusione per il classificatore di foresta casuale con profondità massima di otto, con sei funzionalità:
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()
Creare una matrice di confusione per 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()
Salvare i risultati per Power BI
Salvare il frame differenziale nel lakehouse per spostare i risultati della previsione del modello in una visualizzazione di 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}")
Passaggio 6: accedere alle visualizzazioni in Power BI
Accedere alla tabella salvata in Power BI:
- A sinistra selezionare Hub dati OneLake
- Selezionare il lakehouse aggiunto a questo notebook
- Nella sezione Apri questo lakehouse selezionare Apri
- Nella barra multifunzione selezionare Nuovo modello semantico. Selezionare
df_pred_results
e quindi Continua per creare un nuovo modello semantico di Power BI collegato alle stime - Selezionare Nuovo report dagli strumenti nella parte superiore della pagina dei modelli semantici per aprire la pagina di creazione di report di Power BI
Lo screenshot seguente mostra alcune visualizzazioni di esempio. Il pannello dati mostra le tabelle e le colonne differenziali da selezionare da una tabella. Dopo aver selezionato l'asse delle categorie (x) e quello del valore (y), è possibile scegliere i filtri e le funzioni, ad esempio somma o media della colonna della tabella.
Nota
In questo screenshot l'esempio illustrato descrive l'analisi dei risultati della stima salvata in Power BI:
Tuttavia, per un vero caso d'uso di abbandono dei clienti, l'utente potrebbe avere bisogno di un set più completo dei requisiti delle visualizzazioni da creare, in base alle competenze in materia e a ciò che il team di analisi del business e aziendale, nonché l’azienda stessa hanno standardizzato come metriche.
Il report di Power BI mostra che i clienti che usano più di due prodotti bancari hanno un tasso di abbandono più elevato. Tuttavia, pochi clienti avevano più di due prodotti. (Vedere il tracciato nel pannello in basso a sinistra.) La banca dovrebbe raccogliere più dati, ma dovrebbe anche analizzare altre funzionalità correlate a più prodotti.
I clienti della banca in Germania hanno un tasso di abbandono più elevato rispetto ai clienti in Francia e Spagna. (Vedere il tracciato nel pannello in basso a destra). In base ai risultati del report, potrebbe essere utile svolgere un'indagine sui fattori che hanno incoraggiato i clienti all’abbandono.
Ci sono più clienti di mezza età (tra i 25 e i 45 anni). I clienti tra i 45 e i 60 anni tendono a uscire di più.
Infine, i clienti con punteggi di credito più bassi lasciano la banca per altri istituti finanziari. La banca dovrebbe esplorare i modi per incoraggiare i clienti con punteggi di credito e saldi di conto più bassi a rimanere.
# Determine the entire runtime
print(f"Full run cost {int(time.time() - ts)} seconds.")