Esercitazione: Eseguire il training di un modello in Python con Machine Learning automatizzato

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 apache Spark.
  • Eseguire il training di un modello di regressione in Machine Learning automatizzato.
  • Calcolare l'accuratezza del modello.

Operazioni preliminari

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 Archiviazione 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 usa Spark per eseguire un'analisi sui dati relativi ai suggerimenti per le corse dei taxi da New York City (NYC). 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:

  1. 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.

  2. Poiché i dati non elaborati sono in formato Parquet, è possibile usare il contesto Spark per eseguire il pull del file direttamente in memoria come dataframe. Creare un dataframe Spark recuperando i dati tramite l'API Open Datasets. In questo caso si usano le proprietà del dataframe schema on read 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)
    
    
  3. 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 in modo che sia inferiore, ad esempio un mese di dati, usando i start_date filtri e end_date . Dopo aver filtrato un dataframe, è anche possibile eseguire la describe() funzione nel nuovo dataframe per visualizzare le statistiche di riepilogo 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()
    
  4. Generare funzionalità dal set di dati selezionando un set di colonne e creando diverse funzionalità basate sul tempo dal campo di ritiro datetime . Filtrare gli outlier identificati dal passaggio precedente e quindi rimuovere 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, verrà creato un nuovo dataframe con colonne aggiuntive per il giorno del mese, l'ora di ritiro, il giorno della settimana e il tempo totale di viaggio.

    Picture of taxi DataFrame.

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 suddivide in modo casuale i dati nel set di dati di training per il training del modello e il 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 di Azure Machine Learning TabularDatset . TabularDataset rappresenta i dati in un formato tabulare analizzando i file forniti.

Il codice seguente ottiene l'area di lavoro esistente e l'archivio dati predefinito di Azure Machine Learning. Passa quindi l'archivio dati e i percorsi dei file al parametro path per creare una nuova TabularDataset istanza.

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')])

Picture of uploaded dataset.

Inviare un esperimento automatizzato

Le sezioni seguenti illustrano il processo di invio di un esperimento di Machine Learning automatizzato.

Definire le impostazioni di training

  1. 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}
    
  2. Passare le impostazioni di training definite come parametro kwargs a un oggetto AutoMLConfig. Poiché si usa Spark, è anche necessario passare il contesto di Spark, accessibile automaticamente tramite la variabile sc. 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()

Al termine dell'esperimento, l'output restituisce i dettagli sulle iterazioni completate. Per ogni iterazione, vengono visualizzati il tipo di modello, la durata dell'esecuzione e l'accuratezza del training. Il BEST campo tiene traccia del punteggio di training con esecuzione ottimale in base al tipo di metrica.

Screenshot of model output.

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

  1. 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 predict funzione usa il modello migliore e stima i valori di y (importo della 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)
    
  2. La radice dell'errore quadratico medio viene usata spesso come misura delle differenze tra i valori campione previsti dal modello e i valori osservati. È possibile calcolare l'errore quadratico medio radice dei risultati confrontando il y_test dataframe con i valori stimati 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 distanza delle stime delle tariffe dei taxi dai valori effettivi delle tariffe.

    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.

  3. 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. Esprime quindi tale 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.

  4. 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()
    
    

    Screenshot of a regression plot.

    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. Maggiore sarà la varianza che il modello di regressione rappresenta, più i punti dati saranno più vicini 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 è possibile ottenere altri dettagli sullo stato dell'esecuzione, sui modelli tentati e su altre metriche del modello.

Screenshot of an Azure Machine Learning workspace.

Passaggi successivi