Esercitazione: Eseguire il training di un modello in Python con Machine Learning automatizzato (deprecato)
Azure Machine Learning offre un ambiente basato sul cloud che consente di sottoporre a training, distribuire, automatizzare, gestire e monitorare i modelli di Machine Learning.
In questa esercitazione si userà il servizio Machine Learning automatizzato di Azure Machine Learning per creare un modello di regressione e prevedere i prezzi delle corse dei taxi di New York. Questo processo accetta impostazioni di configurazione e dati di training e scorre automaticamente le combinazioni di diversi metodi, modelli e impostazioni di iperparametri per ottenere il modello migliore.
In questa esercitazione apprenderai a:
- Scaricare i dati usando Apache Spark e i set di dati aperti di Azure.
- Trasformare e pulire i dati usando i DataFrame di Apache Spark.
- Eseguire il training di un modello di regressione in Machine Learning automatizzato.
- Calcolare l'accuratezza del modello.
Operazioni preliminari
- Creare un pool apache Spark 2.4 serverless seguendo la guida introduttiva Creare un pool di Apache Spark serverless.
- Completare l'esercitazione sulla configurazione dell'area di lavoro di Azure Machine Learning, se non è già disponibile un'area di lavoro di Azure Machine Learning.
Avviso
- A partire dal 29 settembre 2023, Azure Synapse interromperà il supporto ufficiale per i runtime di Spark 2.4. Dopo il 29 settembre 2023, non verranno affrontati ticket di supporto correlati a Spark 2.4. Non sarà disponibile alcuna pipeline di versione per correzioni di bug o di sicurezza per Spark 2.4. L'uso di Spark 2.4 dopo la data di scadenza del supporto viene intrapresa a proprio rischio. Sconsigliamo vivamente il suo uso continuo a causa di potenziali problemi di sicurezza e funzionalità.
- Come parte del processo di deprecazione per Apache Spark 2.4, si vuole segnalare che AutoML in Azure Synapse Analytics sarà deprecato. Sono incluse sia l'interfaccia a basso codice che le API usate per creare versioni di valutazione autoML tramite codice.
- Si noti che la funzionalità AutoML era disponibile esclusivamente tramite il runtime di Spark 2.4.
- Per i clienti che vogliono continuare a sfruttare le funzionalità autoML, è consigliabile salvare i dati nell'account Azure Data Lake Storage Gen2 (ADLSg2). Da qui è possibile accedere facilmente all'esperienza AutoML tramite Azure Machine Learning (AzureML). Altre informazioni su questa soluzione alternativa sono disponibili qui.
Informazioni sui modelli di regressione
I modelli di regressione prevedono valori di output numerici basati su predittori indipendenti. Nella regressione l'obiettivo è stabilire la relazione tra le variabili indipendenti del predittore stimando il modo in cui una variabile influisce sulle altre.
Esempio basato sui dati dei taxi di New York
In questo esempio si userà Spark per eseguire un'analisi sui dati relativi alle mance offerte per le corse dei taxi di New York. I dati sono disponibili tramite set di dati aperti di Azure. Questo subset del set di dati contiene informazioni sulle corse dei taxi, incluse informazioni su ogni corsa, l'ora e il luogo di partenza e di arrivo e i costi.
Importante
Per il pull dei dati dalla posizione di archiviazione potrebbero essere addebitati costi aggiuntivi. Nei passaggi successivi verrà sviluppato un modello per prevedere i prezzi delle corse dei taxi di New York.
Scaricare e preparare i dati
In tal caso, eseguire la procedura seguente:
Creare un notebook usando il kernel PySpark. Per le istruzioni, vedere Creare un notebook.
Nota
Dato che è stato usato il kernel PySpark, non è necessario creare contesti in modo esplicito. Il contesto Spark viene creata automaticamente quando si esegue la prima cella di codice.
Poiché i dati non elaborati sono in formato Parquet, è possibile usare il contesto di Spark per eseguire direttamente il pull del file in memoria come DataFrame. Creare un DataFrame di Spark recuperando i dati tramite l'API dei set di dati aperti. In questo caso, verranno usate le proprietà dello
schema on read
dei DataFrame di Spark per dedurre i tipi di dati e lo schema.blob_account_name = "azureopendatastorage" blob_container_name = "nyctlc" blob_relative_path = "yellow" blob_sas_token = r"" # Allow Spark to read from the blob remotely wasbs_path = 'wasbs://%s@%s.blob.core.windows.net/%s' % (blob_container_name, blob_account_name, blob_relative_path) spark.conf.set('fs.azure.sas.%s.%s.blob.core.windows.net' % (blob_container_name, blob_account_name),blob_sas_token) # Spark read parquet; note that it won't load any data yet df = spark.read.parquet(wasbs_path)
A seconda delle dimensioni del pool di Spark, i dati non elaborati potrebbero essere troppo grandi o richiedere troppo tempo per poter essere usati. È possibile filtrare questi dati per ottenere un valore inferiore, ad esempio un mese di dati, usando i filtri
start_date
eend_date
. Una volta filtrato un DataFrame, verrà anche eseguita la funzionedescribe()
sul nuovo DataFrame per visualizzare le statistiche riepilogative per ogni campo.In base alle statistiche riepilogative, si possono notare alcune irregolarità nei dati. Le statistiche indicano, ad esempio, che la distanza minima delle corse è minore di 0. È necessario filtrare questi punti dati irregolari per rimuoverli.
# Create an ingestion filter start_date = '2015-01-01 00:00:00' end_date = '2015-12-31 00:00:00' filtered_df = df.filter('tpepPickupDateTime > "' + start_date + '" and tpepPickupDateTime< "' + end_date + '"') filtered_df.describe().show()
Generare funzionalità dal set di dati selezionando un set di colonne e creando varie funzionalità basate sul tempo dal campo
datetime
di inizio corsa. Verranno inoltre filtrati gli outlier identificati nel passaggio precedente e quindi verranno rimosse le ultime colonne, perché non sono necessarie per il training.from datetime import datetime from pyspark.sql.functions import * # To make development easier, faster, and less expensive, downsample for now sampled_taxi_df = filtered_df.sample(True, 0.001, seed=1234) taxi_df = sampled_taxi_df.select('vendorID', 'passengerCount', 'tripDistance', 'startLon', 'startLat', 'endLon' \ , 'endLat', 'paymentType', 'fareAmount', 'tipAmount'\ , column('puMonth').alias('month_num') \ , date_format('tpepPickupDateTime', 'hh').alias('hour_of_day')\ , date_format('tpepPickupDateTime', 'EEEE').alias('day_of_week')\ , dayofmonth(col('tpepPickupDateTime')).alias('day_of_month') ,(unix_timestamp(col('tpepDropoffDateTime')) - unix_timestamp(col('tpepPickupDateTime'))).alias('trip_time'))\ .filter((sampled_taxi_df.passengerCount > 0) & (sampled_taxi_df.passengerCount < 8)\ & (sampled_taxi_df.tipAmount >= 0)\ & (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 <= 200)\ & (sampled_taxi_df.rateCodeId <= 5)\ & (sampled_taxi_df.paymentType.isin({"1", "2"}))) taxi_df.show(10)
Come si può notare, in questo modo verrà creato un nuovo DataFrame con colonne aggiuntive per il giorno del mese, l'ora di inizio corsa, il giorno della settimana e il tempo totale della corsa.
Generare i set di dati di test e di convalida
Una volta ottenuto il set di dati finale, è possibile dividere i dati in set di training e di test usando la funzione random_ split
in Spark. Usando i pesi forniti, questa funzione divide in modo casuale i dati in set di dati di training per il training del modello e in set di dati di convalida per i test.
# Random split dataset using Spark; convert Spark to pandas
training_data, validation_data = taxi_df.randomSplit([0.8,0.2], 223)
Questo passaggio assicura che per testare il modello finito vengano usati punti dati non usati per eseguirne il training.
Connettersi a un'area di lavoro di Azure Machine Learning
In Azure Machine Learning, workspace è una classe che accetta le informazioni sulla sottoscrizione e sulle risorse di Azure. Crea inoltre una risorsa cloud per monitorare le esecuzioni del modello e tenerne traccia. In questo passaggio verrà creato un oggetto workspace dall'area di lavoro di Azure Machine Learning esistente.
from azureml.core import Workspace
# Enter your subscription id, resource group, and workspace name.
subscription_id = "<enter your subscription ID>" #you should be owner or contributor
resource_group = "<enter your resource group>" #you should be owner or contributor
workspace_name = "<enter your workspace name>" #your workspace name
ws = Workspace(workspace_name = workspace_name,
subscription_id = subscription_id,
resource_group = resource_group)
Convertire un DataFrame in un set di dati di Azure Machine Learning
Per inviare un esperimento remoto, convertire il set di dati in un’istanza TabularDatset
di Azure Machine Learning. Un oggetto TabularDataset rappresenta i dati in formato tabulare analizzando i file forniti.
Il codice seguente ottiene l'area di lavoro esistente e l'archivio dati di Azure Machine Learning. Passa quindi l'archivio dati e i percorsi dei file al parametro path per creare una nuova istanza TabularDataset
.
import pandas
from azureml.core import Dataset
# Get the Azure Machine Learning default datastore
datastore = ws.get_default_datastore()
training_pd = training_data.toPandas().to_csv('training_pd.csv', index=False)
# Convert into an Azure Machine Learning tabular dataset
datastore.upload_files(files = ['training_pd.csv'],
target_path = 'train-dataset/tabular/',
overwrite = True,
show_progress = True)
dataset_training = Dataset.Tabular.from_delimited_files(path = [(datastore, 'train-dataset/tabular/training_pd.csv')])
Inviare un esperimento automatizzato
Le sezioni seguenti illustrano il processo di invio di un esperimento di Machine Learning automatizzato.
Definire le impostazioni di training
Per inviare un esperimento, è necessario definire le relative impostazioni dei parametri e del modello per il training. Per l'elenco completo delle impostazioni, vedere Configurare esperimenti di Machine Learning automatizzato in Python.
import logging automl_settings = { "iteration_timeout_minutes": 10, "experiment_timeout_minutes": 30, "enable_early_stopping": True, "primary_metric": 'r2_score', "featurization": 'auto', "verbosity": logging.INFO, "n_cross_validations": 2}
Passare le impostazioni di training definite come parametro
kwargs
a un oggettoAutoMLConfig
. Poiché si usa Spark, è anche necessario passare il contesto di Spark, accessibile automaticamente tramite la variabilesc
. Inoltre, si specificano i dati di training e il tipo di modello, che in questo caso è regressione.from azureml.train.automl import AutoMLConfig automl_config = AutoMLConfig(task='regression', debug_log='automated_ml_errors.log', training_data = dataset_training, spark_context = sc, model_explainability = False, label_column_name ="fareAmount",**automl_settings)
Nota
I passaggi di pre-elaborazione di Machine Learning automatizzato diventano parte del modello sottostante. Questi passaggi includono la normalizzazione delle funzionalità, la gestione dei dati mancanti e la conversione di testo in valori numerici. Quando si usa il modello per le previsioni, gli stessi passaggi di pre-elaborazione applicati durante il training vengono automaticamente applicati ai dati di input.
Eseguire il training del modello di regressione automatica
Ora creare un oggetto esperimento nell'area di lavoro di Azure Machine Learning. Un esperimento funge da contenitore per le singole esecuzioni.
from azureml.core.experiment import Experiment
# Start an experiment in Azure Machine Learning
experiment = Experiment(ws, "aml-synapse-regression")
tags = {"Synapse": "regression"}
local_run = experiment.submit(automl_config, show_output=True, tags = tags)
# Use the get_details function to retrieve the detailed output for the run.
run_details = local_run.get_details()
Una volta terminato l'esperimento, l'output restituirà i dettagli sulle iterazioni completate. Per ogni iterazione, vengono visualizzati il tipo di modello, la durata dell'esecuzione e l'accuratezza del training. Il campo BEST
traccia il miglior punteggio di training in esecuzione in base del tipo di metrica.
Nota
Una volta inviato, l'esperimento di Machine Learning automatizzato esegue varie iterazioni e tipi di modello. Questa esecuzione richiede in genere da 60 a 90 minuti.
Recuperare il modello migliore
Per selezionare il modello migliore dalle iterazioni, si userà la funzione get_output
, che restituisce l'esecuzione migliore e il modello adattato. Il codice seguente recupera l'esecuzione migliore e il modello adattato per qualsiasi metrica registrata o per un'iterazione specifica.
# Get best model
best_run, fitted_model = local_run.get_output()
Testare l'accuratezza del modello
Per testare l'accuratezza del modello, usare il modello migliore per eseguire previsioni relative alle tariffe dei taxi con il set di dati di test. La funzione
predict
usa il modello migliore e prevede i valori diy
(ovvero la tariffa), dal set di dati di convalida.# Test best model accuracy validation_data_pd = validation_data.toPandas() y_test = validation_data_pd.pop("fareAmount").to_frame() y_predict = fitted_model.predict(validation_data_pd)
La radice dell'errore quadratico medio viene usata spesso come misura delle differenze tra i valori campione previsti dal modello e i valori osservati. Per calcolare la radice dell'errore quadratico medio dei risultati, confrontare il DataFrame
y_test
con i valori previsti dal modello.La funzione
mean_squared_error
calcola l'errore quadratico medio tra due matrici di valori. Eseguire quindi la radice quadrata del risultato. Questa metrica indica approssimativamente la differenza tra le previsioni e i valori effettivi delle tariffe dei taxi.from sklearn.metrics import mean_squared_error from math import sqrt # Calculate root-mean-square error y_actual = y_test.values.flatten().tolist() rmse = sqrt(mean_squared_error(y_actual, y_predict)) print("Root Mean Square Error:") print(rmse)
Root Mean Square Error: 2.309997102577151
La radice dell'errore quadratico medio è una misura valida del livello di accuratezza con cui il modello prevede la risposta. Nei risultati si può notare che la previsione delle tariffe dei taxi eseguita dal modello in base alle caratteristiche del set di dati è piuttosto valida, in genere entro $ 2,00 in eccesso o in difetto.
Eseguire il codice seguente per calcolare l'errore percentuale assoluto medio. Questa metrica esprime l'accuratezza come percentuale dell'errore. Calcola una differenza assoluta tra ogni valore previsto ed effettivo e quindi somma tutte le differenze. Alla fine esprime la somma come percentuale del totale dei valori effettivi.
# Calculate mean-absolute-percent error and model accuracy sum_actuals = sum_errors = 0 for actual_val, predict_val in zip(y_actual, y_predict): abs_error = actual_val - predict_val if abs_error < 0: abs_error = abs_error * -1 sum_errors = sum_errors + abs_error sum_actuals = sum_actuals + actual_val mean_abs_percent_error = sum_errors / sum_actuals print("Model MAPE:") print(mean_abs_percent_error) print() print("Model Accuracy:") print(1 - mean_abs_percent_error)
Model MAPE: 0.03655071038487368 Model Accuracy: 0.9634492896151263
Dalle due metriche dell'accuratezza si nota che la previsione delle tariffe dei taxi eseguita del modello in base alle caratteristiche del set di dati è piuttosto valida.
Dopo aver adattato un modello di regressione lineare, è ora necessario determinare quanto si adatta ai dati. A questo scopo, tracciare i valori delle tariffe effettive rispetto all'output previsto. Calcolare inoltre la misura del coefficiente di determinazione per capire quanto sono vicini i dati alla linea di regressione adattata.
import matplotlib.pyplot as plt import numpy as np from sklearn.metrics import mean_squared_error, r2_score # Calculate the R2 score by using the predicted and actual fare prices y_test_actual = y_test["fareAmount"] r2 = r2_score(y_test_actual, y_predict) # Plot the actual versus predicted fare amount values plt.style.use('ggplot') plt.figure(figsize=(10, 7)) plt.scatter(y_test_actual,y_predict) plt.plot([np.min(y_test_actual), np.max(y_test_actual)], [np.min(y_test_actual), np.max(y_test_actual)], color='lightblue') plt.xlabel("Actual Fare Amount") plt.ylabel("Predicted Fare Amount") plt.title("Actual vs Predicted Fare Amount R^2={}".format(r2)) plt.show()
Nei risultati è possibile osservare che la misura del coefficiente di determinazione rappresenta il 95% della varianza. Questo dato viene anche confermato dal tracciato dei valori effettivi rispetto a quelli osservati. Quanto maggiore è la varianza rappresentata dal modello di regressione, tanto più vicini saranno i punti dati alla linea di regressione adattata.
Registrare il modello in Azure Machine Learning
Dopo aver convalidato il modello migliore, è possibile registrarlo in Azure Machine Learning. Quindi, scaricare o distribuire il modello registrato per ricevere tutti i file registrati.
description = 'My automated ML model'
model_path='outputs/model.pkl'
model = best_run.register_model(model_name = 'NYCYellowTaxiModel', model_path = model_path, description = description)
print(model.name, model.version)
NYCYellowTaxiModel 1
Visualizzare i risultati in Azure Machine Learning
È anche possibile accedere ai risultati delle iterazioni passando all'esperimento nell'area di lavoro di Azure Machine Learning. Qui sarà possibile ottenere informazioni addizionali sullo stato dell'esecuzione, sui modelli provati e su altre metriche dei modelli.