Parte 3 dell'esercitazione: eseguire il training e la registrazione di modelli di Machine Learning
In questa esercitazione si apprenderà come eseguire il training di più modelli di Machine Learning per selezionare quello migliore per stimare quali clienti bancari potrebbero lasciare.
In questa esercitazione si apprenderà come:
- Eseguire il training di modelli Random Forest e LightGBM.
- Usare l'integrazione nativa di Microsoft Fabric con il framework MLflow per registrare i modelli di Machine Learning sottoposti a training, gli iperparametri usati e le metriche di valutazione.
- Registrare il modello di Machine Learning sottoposto a training.
- Valutare le prestazioni dei modelli di Machine Learning sottoposti a training nel set di dati di convalida.
MLflow è una piattaforma open source per la gestione del ciclo di vita di Machine Learning con funzionalità come Rilevamento, Modelli e Registro modelli. MLflow è integrato in modo nativo con l'esperienza di data science di Fabric.
Prerequisiti
Ottenere una sottoscrizione di Microsoft Fabric. In alternativa, iscriversi per ottenere una versione di valutazione di Microsoft Fabric gratuita.
Accedere a Microsoft Fabric.
Utilizza il selettore di esperienza nell'angolo in basso a sinistra della tua home page per passare a Fabric.
Questa è la parte 3 di 5 di questa serie di esercitazioni. Per procedere con questa esercitazione, è necessario completare:
- Parte 1: inserire dati in un lakehouse di Microsoft Fabric usando Apache Spark.
- Parte 2: esplorare e visualizzare i dati usando i notebook di Microsoft Fabric per altre informazioni sui dati.
Seguire la procedura nel notebook
3-train-evaluate.ipynb è il notebook che 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.
Importante
Collegare lo stesso lakehouse usato nella parte 1 e nella parte 2.
Installare librerie personalizzate
Per questo notebook si installerà imbalanced-learn (importato come imblearn
) usando %pip install
. Imbalanced-learn è una libreria per la tecnica di Sovracampionamento delle minoranze sintetiche (SMOTE) usata per gestire set di dati sbilanciati. Il kernel PySpark verrà riavviato dopo %pip install
, quindi sarà necessario installare la libreria prima di eseguire qualsiasi altra cella.
Si accederà a SMOTE usando la libreria imblearn
. Installarlo ora usando le funzionalità di installazione in linea (ad esempio %pip
, %conda
).
# Install imblearn for SMOTE using pip
%pip install imblearn
Importante
Eseguire questa installazione ogni volta che si riavvia il notebook.
Quando si installa una libreria in un notebook, è disponibile solo per la durata della sessione del notebook e non nell'area di lavoro. Se si riavvia il notebook, sarà necessario installare nuovamente la libreria.
Se si ha spesso una libreria usata e si vuole renderla disponibile per tutti i notebook nell'area di lavoro, è possibile usare un ambiente Fabric a tale scopo. È possibile creare un ambiente, installare la libreria e quindi l'amministratore dell'area di lavoro può collegare l'ambiente all'area di lavoro come ambiente predefinito. Per altre informazioni sull'impostazione predefinita di un ambiente, vedere Impostazione predefinita dell'area di lavoro da parte dell'amministratore.
Per eseguire la migrazione delle librerie dell’area di lavoro e delle proprietà di Spark a un ambiente predefinito, vedere Eseguire la migrazione delle librerie dell'area di lavoro e delle proprietà di Spark.
Caricare i dati
Prima di eseguire il training di qualsiasi modello di Machine Learning, è necessario caricare la tabella delta dal lakehouse per leggere i dati puliti creati nel notebook precedente.
import pandas as pd
SEED = 12345
df_clean = spark.read.format("delta").load("Tables/df_clean").toPandas()
Generare un esperimento per tenere traccia e registrare il modello usando MLflow
Questa sezione illustra come generare un esperimento, specificare il modello di Machine Learning e i parametri di training, nonché le metriche di assegnazione dei punteggi, eseguire il training dei modelli di Machine Learning, registrarli e salvare i modelli sottoposti a training per usarli in un secondo momento.
import mlflow
# Setup experiment name
EXPERIMENT_NAME = "bank-churn-experiment" # MLflow experiment name
Estendendo le funzionalità di registrazione automatica di MLflow, la registrazione automatica funziona catturando automaticamente i valori dei parametri di input e delle metriche di output di un modello di machine learning durante il training. Queste informazioni vengono quindi registrate nell'area di lavoro, da cui è possibile accedervi e visualizzarle usando le API MLflow o l'esperimento corrispondente nell'area di lavoro.
Tutti gli esperimenti con i rispettivi nomi vengono registrati e sarà possibile tenere traccia dei parametri e delle metriche delle prestazioni. Per altre informazioni sulla registrazione automatica, vedere Registrazione automatica in Microsoft Fabric.
Impostare le specifiche dell'esperimento e della registrazione automatica
mlflow.set_experiment(EXPERIMENT_NAME)
mlflow.autolog(exclusive=False)
Importare scikit-learn e LightGBM
Con i dati sul posto, è ora possibile definire i modelli di Machine Learning. In questo notebook verranno applicati modelli Random Forest e LightGBM. Usare scikit-learn
e lightgbm
per implementare i modelli in poche righe di codice.
# 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 dati di training e convalida
Usare la funzione train_test_split
da scikit-learn
per suddividere i dati in set di training, convalida e test.
y = df_clean["Exited"]
X = df_clean.drop("Exited",axis=1)
# Split the dataset to 60%, 20%, 20% for training, validation, and test datasets
# Train-Test Separation
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=SEED)
# Train-Validation Separation
X_train, X_val, y_train, y_val = train_test_split(X_train, y_train, test_size=0.25, random_state=SEED)
Salvare i dati di test in una tabella delta
Salvare i dati di test nella tabella delta da usare nel notebook successivo.
table_name = "df_test"
# Create PySpark DataFrame from Pandas
df_test=spark.createDataFrame(X_test)
df_test.write.mode("overwrite").format("delta").save(f"Tables/{table_name}")
print(f"Spark test DataFrame saved to delta table: {table_name}")
Applicare SMOTE ai dati di training per sintetizzare nuovi esempi per la classe di minoranza
L'esplorazione dei dati nella parte 2 ha mostrato che dei 10.000 punti dati corrispondenti a 10.000 clienti, solo 2.037 clienti (circa il 20%) hanno lasciato la banca. Ciò indica che il set di dati è altamente sbilanciato. Il problema della classificazione sbilanciata è che ci sono troppi esempi della classe di minoranza per un modello per apprendere efficacemente il limite decisionale. SMOTE è l'approccio più diffuso per sintetizzare nuovi esempi per la classe di minoranza. Altre informazioni su SMOTE sono disponibili qui e qui.
Suggerimento
Si noti che SMOTE deve essere applicato solo al set di dati di training. È necessario lasciare il set di dati di test nella distribuzione originale sbilanciata per ottenere un'approssimazione valida del modo in cui il modello di Machine Learning eseguirà sui dati originali, che rappresenta la situazione nell'ambiente di 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)
Suggerimento
È possibile ignorare in modo sicuro il messaggio di avviso MLflow visualizzato quando si esegue questa cella.
Se viene visualizzato un messaggio ModuleNotFoundError, non è stata eseguita la prima cella in questo notebook, che installa la libreria imblearn
. È necessario installare questa libreria ogni volta che si riavvia il notebook. Tornare indietro ed eseguire di nuovo tutte le celle a partire dalla prima cella di questo notebook.
Training del modello
- Eseguire il training del modello usando Random Forest con una profondità massima di 4 e 4 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) # Imbalanaced training data
rfc1_sm.fit(X_res, y_res.ravel()) # Balanced training data
rfc1_sm.score(X_val, y_val)
y_pred = rfc1_sm.predict(X_val)
cr_rfc1_sm = classification_report(y_val, y_pred)
cm_rfc1_sm = confusion_matrix(y_val, y_pred)
roc_auc_rfc1_sm = roc_auc_score(y_res, rfc1_sm.predict_proba(X_res)[:, 1])
- Eseguire il training del modello usando Random Forest con una profondità massima di 8 e 6 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_val, y_val)
y_pred = rfc2_sm.predict(X_val)
cr_rfc2_sm = classification_report(y_val, y_pred)
cm_rfc2_sm = confusion_matrix(y_val, y_pred)
roc_auc_rfc2_sm = roc_auc_score(y_res, rfc2_sm.predict_proba(X_res)[:, 1])
- Eseguire il training del modello usando 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_val)
accuracy = accuracy_score(y_val, y_pred)
cr_lgbm_sm = classification_report(y_val, y_pred)
cm_lgbm_sm = confusion_matrix(y_val, y_pred)
roc_auc_lgbm_sm = roc_auc_score(y_res, lgbm_sm_model.predict_proba(X_res)[:, 1])
Artefatto degli esperimenti per tenere traccia delle prestazioni del modello
Le esecuzioni dell'esperimento vengono salvate automaticamente nell'artefatto dell'esperimento che è possibile trovare dall'area di lavoro. Vengono denominati in base al nome usato per impostare l'esperimento. Vengono registrati tutti i modelli di Machine Learning sottoposti a training, le relative esecuzioni, le metriche delle prestazioni e i parametri del modello.
Per visualizzare gli esperimenti:
Nel pannello a sinistra, selezionare l'area di lavoro.
In alto a destra filtrare in modo da visualizzare solo gli esperimenti, per semplificare l'individuazione dell'esperimento che si sta cercando.
Trovare e selezionare il nome dell'esperimento, in questo caso bank-churn-experiment. Se l'esperimento non viene visualizzato nell'area di lavoro, aggiornare il browser.
Valutare le prestazioni dei modelli sottoposti a training nel set di dati di convalida
Al termine del training dei modelli di Machine Learning, è possibile valutare le prestazioni dei modelli sottoposti a training in due modi.
Aprire l'esperimento salvato dall'area di lavoro, caricare i modelli di Machine Learning e quindi valutare le prestazioni dei modelli caricati nel set di dati di convalida.
# 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") # Assess the performance of the loaded model on validation dataset ypred_rfc1_sm_v1 = load_model_rfc1_sm.predict(X_val) # Random Forest with max depth of 4 and 4 features ypred_rfc2_sm_v1 = load_model_rfc2_sm.predict(X_val) # Random Forest with max depth of 8 and 6 features ypred_lgbm1_sm_v1 = load_model_lgbm1_sm.predict(X_val) # LightGBM
Valutare direttamente le prestazioni dei modelli di Machine Learning sottoposti a training nel set di dati di convalida.
ypred_rfc1_sm_v2 = rfc1_sm.predict(X_val) # Random Forest with max depth of 4 and 4 features ypred_rfc2_sm_v2 = rfc2_sm.predict(X_val) # Random Forest with max depth of 8 and 6 features ypred_lgbm1_sm_v2 = lgbm_sm_model.predict(X_val) # LightGBM
A seconda della preferenza, entrambi gli approcci sono ottimi e dovrebbero offrire prestazioni identiche. In questo notebook si sceglierà il primo approccio per illustrare meglio le funzionalità di registrazione automatica di MLflow in Microsoft Fabric.
Mostra veri/falsi positivi/negativi usando la matrice di confusione
Successivamente, si svilupperà uno script per tracciare la matrice di confusione per valutare l'accuratezza della classificazione usando il set di dati di convalida. La matrice di confusione può essere tracciata anche usando gli strumenti SynapseML, come illustrato nell'esempio di rilevamento delle frodi disponibile qui.
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 itertools
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')
- Matrice di confusione per il classificatore di Random Forest con profondità massima di 4 e 4 funzionalità
cfm = confusion_matrix(y_val, y_pred=ypred_rfc1_sm_v1)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
title='Random Forest with max depth of 4')
tn, fp, fn, tp = cfm.ravel()
- Matrice di confusione per il classificatore di Random Forest con profondità massima di 8 e 6 funzionalità
cfm = confusion_matrix(y_val, y_pred=ypred_rfc2_sm_v1)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
title='Random Forest with max depth of 8')
tn, fp, fn, tp = cfm.ravel()
- Matrice di confusione per LightGBM
cfm = confusion_matrix(y_val, y_pred=ypred_lgbm1_sm_v1)
plot_confusion_matrix(cfm, classes=['Non Churn','Churn'],
title='LightGBM')
tn, fp, fn, tp = cfm.ravel()