Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
In questo articolo si apprenderà come eseguire il training dei modelli di classificazione usando i computer EBM (Explainable Boosting Machines). Un computer con boosting spiegabile è una tecnica di Machine Learning che combina la potenza di boosting delle sfumature con un'enfasi sull'interpretazione del modello. Crea un insieme di alberi delle decisioni, simile all'aumento delle sfumature, ma con particolare attenzione alla generazione di modelli leggibili. Gli EBM non solo forniscono stime accurate, ma offrono anche spiegazioni chiare e intuitive per tali stime. Sono ideali per le applicazioni in cui la comprensione dei fattori sottostanti che guidano le decisioni del modello è essenziale, ad esempio assistenza sanitaria, finanza e conformità alle normative.
In SynapseML è possibile usare un'implementazione scalabile di un EBM, basato su Apache Spark, per il training di nuovi modelli. Questo articolo illustra il processo di applicazione della scalabilità e dell'interpretazione di EBMs all'interno di Microsoft Fabric usando Apache Spark.
Importante
Questa funzionalità si trova nell’anteprima.
In questo articolo viene illustrato il processo di acquisizione e pre-elaborazione dei dati da Set di dati aperti di Azure che registra le corse dei taxi gialli di New York. Si esegue quindi il training di un modello predittivo con l'obiettivo finale di determinare se si verificherà o meno un determinato viaggio.
Vantaggi dei computer con boosting spiegabili
Gli EBM offrono una combinazione unica di interpretabilità e potenza predittiva, rendendoli una scelta ideale quando la trasparenza e la comprensione dei modelli di Machine Learning sono fondamentali. Con gli EBM, gli utenti possono ottenere informazioni utili sui fattori sottostanti che guidano le stime, consentendo loro di comprendere perché un modello prende decisioni o stime specifiche, essenziale per creare fiducia nei sistemi di intelligenza artificiale.
La loro capacità di individuare relazioni complesse all'interno dei dati fornendo risultati chiari e interpretabili li rende preziosi in campi come finanza, sanità e rilevamento delle frodi. In questi campi, la spiegazione del modello non è solo auspicabile, ma spesso un requisito normativo. In definitiva, gli utenti che scelgono gli EBM possono trovare un equilibrio tra le prestazioni del modello e la trasparenza, assicurando che le soluzioni di intelligenza artificiale siano accurate, facilmente comprensibili e responsabili.
Prerequisiti
Ottenere una sottoscrizione di Microsoft Fabric. In alternativa, iscriversi per ottenere una versione di valutazione di Microsoft Fabric gratuita.
Accedere a Microsoft Fabric.
Passare a Fabric usando il commutatore dell'esperienza in basso a sinistra della tua home page.
- Creare un nuovo notebook nell'area di lavoro selezionando + e quindi Notebook.
Installare le librerie
Per iniziare, installare la libreria Open Datasets di Azure Machine Learning, che concede l'accesso al set di dati. Questo passaggio di installazione è essenziale per l'accesso e l'uso efficace del set di dati.
%pip install azureml-opendatasets
Importare MLflow
MLflow consente di tenere traccia dei parametri e dei risultati del modello. Il frammento di codice seguente illustra come usare MLflow per scopi di sperimentazione e rilevamento. Il valore ebm_classification_nyc_taxi è il nome dell'esperimento in cui vengono registrate le informazioni.
import mlflow
# Set up the experiment name
mlflow.set_experiment("ebm_classification_nyc_taxi")
Importare le librerie
Aggiungere quindi il codice seguente per importare i pacchetti essenziali usati per l'analisi:
# Import necessary packages
import interpret
from pyspark.ml.feature import StringIndexer, VectorAssembler
from pyspark.ml import Pipeline
from pyspark.mllib.evaluation import BinaryClassificationMetrics
from pyspark.sql import SparkSession
from pyspark.sql.functions import *
from pyspark.sql.types import DoubleType
from synapse.ml.ebm import EbmClassification
Questi pacchetti importati forniscono gli strumenti e le funzionalità fondamentali necessari per le attività di analisi e modellazione.
Caricare i dati
Aggiungere quindi il codice seguente per recuperare i dati dei taxi gialli di New York da Set di dati aperti di Azure Machine Learning e, facoltativamente, eseguire il down-sample del set di dati per accelerare lo sviluppo:
# Import NYC Yellow Taxi data from Azure Open Datasets
from azureml.opendatasets import NycTlcYellow
from datetime import datetime
from dateutil import parser
# Define the start and end dates for the dataset
end_date = parser.parse('2018-05-08 00:00:00')
start_date = parser.parse('2018-05-01 00:00:00')
# Load the NYC Yellow Taxi dataset within the specified date range
nyc_tlc = NycTlcYellow(start_date=start_date, end_date=end_date)
nyc_pd = nyc_tlc.to_pandas_dataframe()
nyc_tlc_df = spark.createDataFrame(nyc_pd)
Per facilitare lo sviluppo e ridurre il sovraccarico di calcolo, è possibile eseguire il down-sample del set di dati:
# For development convenience, consider down-sampling the dataset
sampled_taxi_df = nyc_tlc_df.sample(True, 0.001, seed=1234)
Il campionamento inattivo consente un'esperienza di sviluppo più rapida e conveniente, in particolare quando si lavora con set di dati di grandi dimensioni.
Preparare i dati
In questa sezione si prepara il set di dati filtrando le righe con outlier e variabili irrilevanti.
Generare funzionalità
Creare codice per le nuove funzionalità derivate previste per migliorare le prestazioni del modello:
taxi_df = sampled_taxi_df.select('totalAmount', 'fareAmount', 'tipAmount', 'paymentType', 'rateCodeId', 'passengerCount',
'tripDistance', 'tpepPickupDateTime', 'tpepDropoffDateTime',
date_format('tpepPickupDateTime', 'hh').alias('pickupHour'),
date_format('tpepPickupDateTime', 'EEEE').alias('weekdayString'),
(unix_timestamp(col('tpepDropoffDateTime')) - unix_timestamp(col('tpepPickupDateTime'))).alias('tripTimeSecs'),
(when(col('tipAmount') > 0, 1).otherwise(0)).alias('tipped')
)\
.filter((sampled_taxi_df.passengerCount > 0) & (sampled_taxi_df.passengerCount < 8)
& (sampled_taxi_df.tipAmount >= 0) & (sampled_taxi_df.tipAmount <= 25)
& (sampled_taxi_df.fareAmount >= 1) & (sampled_taxi_df.fareAmount <= 250)
& (sampled_taxi_df.tipAmount < sampled_taxi_df.fareAmount)
& (sampled_taxi_df.tripDistance > 0) & (sampled_taxi_df.tripDistance <= 100)
& (sampled_taxi_df.rateCodeId <= 5)
& (sampled_taxi_df.paymentType.isin({"1", "2"}))
)
Dopo aver creato nuove variabili, aggiungere codice per eliminare le colonne da cui sono state derivate. Il dataframe è ora più semplificato per l'input del modello. Inoltre, è possibile generare altre funzionalità in base alle colonne appena create:
taxi_featurised_df = taxi_df.select('totalAmount', 'fareAmount', 'tipAmount', 'paymentType', 'passengerCount',
'tripDistance', 'weekdayString', 'pickupHour', 'tripTimeSecs', 'tipped',
when((taxi_df.pickupHour <= 6) | (taxi_df.pickupHour >= 20), "Night")
.when((taxi_df.pickupHour >= 7) & (taxi_df.pickupHour <= 10), "AMRush")
.when((taxi_df.pickupHour >= 11) & (taxi_df.pickupHour <= 15), "Afternoon")
.when((taxi_df.pickupHour >= 16) & (taxi_df.pickupHour <= 19), "PMRush")
.otherwise(0).alias('trafficTimeBins'))\
.filter((taxi_df.tripTimeSecs >= 30) & (taxi_df.tripTimeSecs <= 7200))
Questi passaggi di preparazione dei dati assicurano che il set di dati sia ottimizzato per i processi di modellazione successivi.
Codificare i dati
Nel contesto di EBMs SynapseML, Estimator prevede che i dati di input siano sotto forma di org.apache.spark.mllib.linalg.Vector, essenzialmente un vettore di Doubles. È quindi necessario convertire qualsiasi variabile categorica (stringa) in rappresentazioni numeriche e tutte le variabili che possiedono valori numerici, ma i tipi di dati non numerici devono essere inseriti in tipi di dati numerici.
Attualmente, gli EBM synapseML usano l'approccio StringIndexer per gestire le variabili categoriche. Attualmente, gli EBM SynapseML non offrono una gestione specializzata per le funzionalità categoriche.
Ecco una serie di passaggi da aggiungere al codice per preparare i dati da usare con gli EBM SynapseML:
# Convert categorical features into numerical representations using StringIndexer
sI1 = StringIndexer(inputCol="trafficTimeBins", outputCol="trafficTimeBinsIndex")
sI2 = StringIndexer(inputCol="weekdayString", outputCol="weekdayIndex")
# Apply the encodings to create a new dataframe
encoded_df = Pipeline(stages=[sI1, sI2]).fit(taxi_featurised_df).transform(taxi_featurised_df)
final_df = encoded_df.select('fareAmount', 'paymentType', 'passengerCount', 'tripDistance',
'pickupHour', 'tripTimeSecs', 'trafficTimeBinsIndex', 'weekdayIndex',
'tipped')
# Ensure that any string representations of numbers in the data are cast to numeric data types
final_df = final_df.withColumn('paymentType', final_df['paymentType'].cast(DoubleType()))
final_df = final_df.withColumn('pickupHour', final_df['pickupHour'].cast(DoubleType()))
# Define the label column name
labelColumnName = 'tipped'
# Assemble the features into a vector
assembler = VectorAssembler(outputCol='features')
assembler.setInputCols([c for c in final_df.columns if c != labelColumnName])
vectorized_final_df = assembler.transform(final_df)
Questi passaggi di preparazione dei dati sono fondamentali per allineare il formato dei dati ai requisiti degli EBM SynapseML, garantendo un training accurato ed efficace del modello.
Generare set di dati di training e di test
Aggiungere ora il codice per dividere il set di dati in set di training e test usando una suddivisione semplice. Il 70% dei dati viene allocato per il training e il 30% per il test del modello:
# Decide on the split between training and test data from the dataframe
trainingFraction = 0.7
testingFraction = (1-trainingFraction)
seed = 1234
# Split the dataframe into test and training dataframes
train_data_df, test_data_df = vectorized_final_df.randomSplit([trainingFraction, testingFraction], seed=seed)
Questa divisione dei dati consente di eseguire il training del modello su una parte sostanziale riservando un'altra parte per valutarne in modo efficace le prestazioni.
Eseguire il training del modello
Aggiungere ora il codice per eseguire il training del modello EBM e quindi valutarne le prestazioni usando l'Area sotto la curva ROC (Receiver Operating Characteristic) come metrica:
# Create an instance of the EBMClassifier
estimator = EbmClassification()
estimator.setLabelCol(labelColumnName)
# Fit the EBM model to the training data
model = estimator.fit(train_data_df)
# Make predictions for tip (1/0 - yes/no) on the test dataset and evaluate using AUROC
predictions = model.transform(test_data_df)
predictionsAndLabels = predictions.select("prediction", labelColumnName)
predictionsAndLabels = predictionsAndLabels.withColumn(labelColumnName, predictionsAndLabels[labelColumnName].cast(DoubleType()))
# Calculate AUROC using BinaryClassificationMetrics
metrics = BinaryClassificationMetrics(predictionsAndLabels.rdd)
print("Area under ROC = %s" % metrics.areaUnderROC)
Questo processo comporta il training del modello EBM nel set di dati di training e quindi l'utilizzo per eseguire stime sul set di dati di test, seguito dalla valutazione delle prestazioni del modello tramite AUROC come metrica chiave.
Visualizzare le spiegazioni globali
Per visualizzare la spiegazione complessiva del modello, è possibile aggiungere codice per ottenere il wrapper di visualizzazione e usare il interpret metodo della show libreria. Il wrapper di visualizzazione funge da ponte per facilitare l'esperienza di visualizzazione del modello. È necessario seguire questa procedura:
wrapper = model.getVizWrapper()
explanation = wrapper.explain_global()
Aggiungere quindi il codice per importare la interpret libreria e usare il show metodo per visualizzare la spiegazione:
import interpret
interpret.show(explanation)
Screenshot delle spiegazioni globali.
Il termine "priorità" rappresenta il contributo assoluto medio (punteggio) di ogni termine (funzionalità o interazione) verso le stime. Questi contributi vengono calcolati in media nel set di dati di training, tenendo conto del numero di campioni in ogni contenitore e pesi campione (se applicabile). Nella spiegazione vengono visualizzati i primi 15 termini più importanti.
Visualizzare le spiegazioni locali
Le spiegazioni fornite sono a livello globale, ma esistono scenari in cui anche gli output per funzionalità sono utili. Sia il formatore che il modello offrono la possibilità di impostare, featurescores, che, se popolato, introduce un'altra colonna con valori vettoriali. Ogni vettore all'interno di questa colonna corrisponde alla lunghezza della colonna di funzionalità, con ogni valore corrispondente alla funzionalità nello stesso indice. Questi valori rappresentano il contributo del valore di ogni funzionalità all'output finale del modello.
A differenza delle spiegazioni globali, attualmente non esiste alcuna integrazione diretta con la visualizzazione interpret per gli output per funzionalità. Ciò è dovuto al fatto che le visualizzazioni globali vengono ridimensionate principalmente con il numero di funzionalità (in genere ridotte), mentre le spiegazioni locali vengono ridimensionate con il numero di righe (che, se un dataframe Spark, può essere sostanziale).
Ecco il codice da aggiungere per configurare e usare :featurescores
prediction2 = model.setFeatureScoresCol("featurescores").transform(train_data_df)
Ai fini dell'illustrazione, aggiungere il codice per stampare i dettagli del primo esempio:
# Convert to Pandas for easier inspection
predictions_pandas = prediction2.toPandas()
predictions_list = prediction2.collect()
# Extract the first example from the collected predictions.
first = predictions_list[0]
# Print the lengths of the features and feature scores.
print('Length of the features is', len(first['features']), 'while the feature scores have length', len(first['featurescores']))
# Print the values of the features and feature scores.
print('Features are', first['features'])
print('Feature scores are', first['featurescores'])