Utilizzo dei dati meteorologici per modelli di apprendimento automatico

Utilizzo dati meteorologici per modelli di apprendimento automatico

Introduzione

Il tempo atmosferico è un fattore determinante per molte cose che accadono nel mondo reale. In effetti, è così importante che di solito finisce per beneficiare qualsiasi modello di previsione che lo incorpora utilizzando modelli di apprendimento automatico.

Pensate ai seguenti scenari:

  • Un’agenzia di trasporto pubblico cerca di prevedere ritardi e congestioni nel sistema
  • Un fornitore di energia desidera stimare la quantità di energia elettrica solare prodotta domani per scopi di scambio energetico
  • Gli organizzatori di eventi devono anticipare il numero di partecipanti al fine di garantire il rispetto delle norme di sicurezza
  • Un’azienda agricola deve pianificare le operazioni di raccolta per la prossima settimana

È lecito dire che qualsiasi modello negli scenari sopra descritti che non includa il tempo atmosferico come fattore è o inutile o non così buono come potrebbe essere.

Sorprendentemente, mentre ci sono molte risorse online che si concentrano su come prevedere il tempo atmosferico stesso, non c’è praticamente nulla che mostri come ottenere e utilizzare efficacemente i dati meteorologici come caratteristica, cioè come input per prevedere qualcos’altro. Di questo tratta questo post.

Panoramica

Inizieremo evidenziando le sfide associate all’utilizzo dei dati meteorologici per la modellazione, quali modelli sono comunemente utilizzati e quali fornitori sono disponibili. Poi eseguiremo uno studio di caso e utilizzeremo i dati di uno dei fornitori per costruire un modello di apprendimento automatico che prevede i taxi a New York.

Alla fine di questo post avrete imparato:

  • Sfide legate all’utilizzo dei dati meteorologici per la modellazione
  • Quali modelli e fornitori di previsioni meteorologiche esistono
  • Tipiche fasi di estrazione, trasformazione e caricamento dei dati e creazione delle caratteristiche per i dati di serie temporali
  • Valutazione dell’importanza delle caratteristiche utilizzando i valori SHAP

Questo articolo è stato pubblicato come parte del Data Science Blogathon.

Sfide

Dati meteorologici misurati vs previsioni

Per un modello di apprendimento automatico in produzione abbiamo bisogno sia (1) di dati in tempo reale per produrre previsioni in tempo reale sia (2) di un insieme di dati storici per addestrare un modello in grado di fare una cosa del genere.

di Hadija su Unsplash

Ovviamente, quando si effettuano previsioni in tempo reale, utilizzeremo le previsioni meteorologiche attuali come input, in quanto rappresentano la stima più aggiornata di ciò che accadrà in futuro. Ad esempio, quando si prevede quanta energia solare verrà prodotta domani, l’input del modello di cui abbiamo bisogno è ciò che le previsioni dicono sul tempo di domani.

E per l’addestramento del modello?

Se vogliamo che il modello si comporti bene nel mondo reale, i dati di addestramento devono riflettere i dati in tempo reale. Per l’addestramento del modello, si deve fare una scelta su se utilizzare misure storiche o previsioni storiche. Le misure storiche riflettono solo l’esito, cioè ciò che le stazioni meteorologiche hanno registrato. Tuttavia, il modello in tempo reale utilizzerà le previsioni, non le misure, poiché le misure non sono ancora disponibili al momento in cui il modello effettua la sua previsione.

Se c’è la possibilità di ottenere previsioni storiche, dovrebbero essere sempre preferite, poiché addestrano il modello nelle stesse condizioni esatte disponibili al momento delle previsioni in tempo reale.

dell'American Public Power Association su Unsplash

Considerate questo esempio: ogni volta che ci sono molte nuvole, un impianto di energia solare produrrà poca elettricità. Un modello addestrato su misure storiche imparerà che quando la caratteristica della copertura nuvolosa mostra un valore alto, c’è una probabilità del 100% che non ci sarà molta elettricità. D’altra parte, un modello addestrato su previsioni storiche imparerà che c’è un’altra dimensione in questo: la distanza di previsione. Quando si effettuano previsioni diversi giorni in anticipo, un valore alto per la copertura nuvolosa è solo una stima e non significa che il giorno in questione sarà nuvoloso con certezza. In tali casi, il modello sarà in grado di fare affidamento solo in parte su questa caratteristica e considerare anche altre caratteristiche quando prevede la generazione solare.

Formato

I dati meteorologici ≠ dati meteorologici. Ci sono molti fattori che escludono un insieme specifico di dati meteorologici come remotamente utili. Tra i principali fattori ci sono:

  • Granularità: ci sono registrazioni per ogni ora, ogni 3 ore, giornaliere?
  • Variabili: include la/e caratteristica/e di cui ho bisogno?
  • Risoluzione spaziale: a quanti km² si riferisce una singola registrazione?
  • Orizzonte: fino a quando va la previsione?
  • Aggiornamenti della previsione: con quale frequenza viene creata una nuova previsione?

Inoltre, la forma o il formato dei dati possono essere complessi da lavorare. Eventuali passaggi aggiuntivi di ETL che devi creare possono introdurre errori e la natura temporale dei dati può rendere questo lavoro piuttosto frustrante.

Dati live vs. dati vecchi

I dati più vecchi di un giorno, o di una settimana, spesso arrivano in forma di file CSV, server FTP o al massimo su un endpoint API separato, ma spesso con campi diversi rispetto all’endpoint delle previsioni in tempo reale. Questo crea il rischio di dati non corrispondenti e può aumentare la complessità nella tua ETL.

Costi

I costi possono variare notevolmente a seconda del fornitore e dei tipi di dati meteorologici richiesti. Ad esempio, i fornitori possono addebitare per ogni coordinata singola, il che può essere un problema quando sono necessarie molte posizioni. Ottenere previsioni meteorologiche storiche è generalmente piuttosto difficile e costoso.

Modelli meteorologici

I modelli di previsione meteorologica numerica, come vengono spesso chiamati, simulano il comportamento fisico di tutti i diversi aspetti del tempo. Ce ne sono molti, che variano nel loro formato (vedi sopra), nelle parti del globo che coprono e nella precisione.

Ecco un elenco rapido dei modelli meteorologici più utilizzati:

  • GFS: modello standard più conosciuto, ampiamente utilizzato, globale
  • CFS: meno accurato rispetto al GFS, per previsioni climatiche a lungo termine, globale
  • ECMWF: modello più accurato ma costoso, globale
  • UM: modello più accurato per il Regno Unito, globalmente disponibile
  • WRF: codice open source per produrre previsioni meteorologiche regionali fai-da-te
di Brian McGowan su Unsplash

Fornitori

I fornitori sono lì per portare i dati dai modelli meteorologici all’utente finale. Spesso hanno anche i loro modelli di previsione proprietari oltre ai modelli meteorologici standard. Ecco alcuni dei più noti:

  • AccuWeather
  • MetOffice
  • OpenWeatherMap
  • AerisWeather
  • DWD (Germania)
  • Meteogroup (Regno Unito)

BlueSky API

Per il caso d’uso del machine learning, i fornitori sopra menzionati si rivelano o non offrono previsioni storiche o il processo per ottenere e combinare i dati è sia complicato che costoso. In contrasto, blueskyapi.io offre un’API semplice che può essere chiamata per ottenere sia previsioni in tempo reale che storiche nello stesso formato, rendendo la pipeline dei dati molto semplice. I dati originali provengono dal GFS, il modello meteorologico più ampiamente utilizzato.

Studio di caso: Corse in taxi a New York

Immagina di possedere un’azienda di taxi a New York e di voler prevedere il numero di corse in taxi per ottimizzare la pianificazione del personale e della flotta. Poiché hai accesso ai dati storici combinati dei taxi di New York, decidi di utilizzarli e creare un modello di machine learning.

di Heather Shevlin su Unsplash

Useremo i dati che possono essere scaricati dal sito web di NYC qui.

Prima di tutto, alcuni import:

import pandas as pd
import numpy as np
import holidays
import datetime
import pytz
from dateutil.relativedelta import relativedelta
from matplotlib import pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestRegressor
import shap
import pyarrow

Preelaborazione dei dati dei taxi

timezone = pytz.timezone("US/Eastern")
dates = pd.date_range("2022-04", "2023-03", freq="MS", tz=timezone)

Per ottenere il nostro set di dati dei taxi, dobbiamo scorrere i file e creare un dataframe aggregato con il conteggio per ora. Questo richiederà circa 20 secondi per essere completato.

aggregated_dfs = []
for date in dates:
    print(date)
    df = pd.read_parquet(
      f"./data/yellow_tripdata_{date.strftime('%Y-%m')}.parquet", 
      engine='pyarrow'
    )
    df["timestamp"] = pd.DatetimeIndex(
      df["tpep_pickup_datetime"], tz=timezone, ambiguous='NaT'
    ).floor("H")
    
    # pulizia dei dati, a volte include timestamp errati
    df = df[
        (df.timestamp >= date) & 
        (df.timestamp < date + relativedelta(months=1))
    ]
    aggregated_dfs.append(
      df.groupby(["timestamp"]).agg({"trip_distance": "count"}
    ).reset_index())
df = pd.concat(aggregated_dfs).reset_index(drop=True)
df.columns = ["timestamp", "count"]

Diamo un’occhiata ai dati. Primi 2 giorni:

df.head(48).plot("timestamp", "count")

Tutto:

fig, ax = plt.subplots()
fig.set_size_inches(20, 8)
ax.plot(df.timestamp, df["count"])
ax.xaxis.set_major_locator(plt.MaxNLocator(10))

Curiosamente, possiamo vedere che durante alcuni periodi festivi il numero di corse in taxi è piuttosto ridotto. Dal punto di vista delle serie temporali non vi è alcuna tendenza o eteroschedasticità evidente nei dati.

Ingegneria delle caratteristiche dei dati dei taxi

Successivamente, aggiungeremo alcune caratteristiche tipiche utilizzate nella previsione delle serie temporali.

Codifica delle parti del timestamp

df["hour"] = df["timestamp"].dt.hour
df["day_of_week"] = df["timestamp"].dt.day_of_week

Codifica dei giorni festivi

us_holidays = holidays.UnitedStates()
df["date"] = df["timestamp"].dt.date
df["holiday_today"] = [ind in us_holidays for ind in df.date]
df["holiday_tomorrow"] = [ind + datetime.timedelta(days=1) in us_holidays for ind in df.date]
df["holiday_yesterday"] = [ind - datetime.timedelta(days=1) in us_holidays for ind in df.date]

Dati meteo BlueSky

Ora arriviamo alla parte interessante: i dati meteorologici. Di seguito è riportata una spiegazione su come utilizzare l’API BlueSky weather. Per gli utenti di Python, è disponibile tramite pip:

pip install blueskyapi

Tuttavia, è anche possibile utilizzare cURL.

L’API di base di BlueSky è gratuita. Si consiglia di ottenere una chiave API tramite il sito web, in quanto ciò aumenterà la quantità di dati che è possibile estrarre dall’API.

Con la loro sottoscrizione a pagamento, è possibile ottenere variabili meteorologiche aggiuntive, aggiornamenti delle previsioni più frequenti, una maggiore granularità, ecc., ma per lo studio di caso questo non è necessario.

import blueskyapi
client = blueskyapi.Client()  # utilizzare qui la chiave API per aumentare il limite dati

Dobbiamo scegliere la posizione, le distanze delle previsioni e le variabili meteorologiche di interesse. Otteniamo un anno completo di previsioni meteorologiche per abbinarle ai dati dei taxi.

# New York
lat = 40.5
lon = 106.0

weather = client.forecast_history(
    lat=lat,
    lon=lon,
    min_forecast_moment="2022-04-01T00:00:00+00:00",
    max_forecast_moment="2023-04-01T00:00:00+00:00",
    forecast_distances=[3,6],  # ore in anticipo
    columns=[
        'precipitation_rate_at_surface',
        'apparent_temperature_at_2m',
        'temperature_at_2m',
        'total_cloud_cover_at_convective_cloud_layer',
        'wind_speed_gust_at_surface',
        'categorical_rain_at_surface',
        'categorical_snow_at_surface'
    ],
)
weather.iloc[0]

Ecco tutto quello che dovevamo fare per ottenere i dati meteorologici!

Unisci i dati

Dobbiamo assicurarci che i dati meteorologici vengano mappati correttamente con i dati dei taxi. Per farlo, abbiamo bisogno del momento target in cui è stata effettuata la previsione del tempo. Lo otteniamo aggiungendo forecast_moment + forecast_distance:

weather["target_moment"] = weather.forecast_moment + pd.to_timedelta(
    weather.forecast_distance, unit="h"
)

Un problema tipico quando si uniscono i dati è il tipo di dato e la consapevolezza del fuso orario dei timestamp. Allineiamo i fusi orari per assicurarci di unirli correttamente.

df["timestamp"] = [timezone.normalize(ts).astimezone(pytz.utc) for ts in df["timestamp"]]
weather["target_moment"] = weather["target_moment"].dt.tz_localize('UTC')

Come ultimo passaggio, uniamo, per ogni timestamp nei dati dei taxi, la previsione meteorologica più recente disponibile ad esso.

d = pd.merge_asof(df, weather, left_on="timestamp", right_on="target_moment", direction="nearest")
d.iloc[0]

Il nostro dataset è completo!

Modello

Prima di modellare, ha spesso senso verificare un paio di cose in più, come ad esempio se la variabile target è stazionaria e se ci sono mancanze o anomalie nei dati. Tuttavia, per il bene di questo post sul blog, procediamo in modo molto semplice e andiamo avanti con un modello random forest predefinito con le caratteristiche che abbiamo estratto e creato:

d = d[~d.isnull().any(axis=1)].reset_index(drop=True)
X = d[
    [
        "day_of_week", 
        "hour", 
        "holiday_today", 
        "holiday_tomorrow", 
        "holiday_yesterday", 
        "precipitation_rate_at_surface",
        "apparent_temperature_at_2m",
        "temperature_at_2m",
        "total_cloud_cover_at_convective_cloud_layer",
        "wind_speed_gust_at_surface",
        "categorical_rain_at_surface",
        "categorical_snow_at_surface"
    ]
]
y = d["count"]
X_train, X_test, y_train, y_test = train_test_split(
  X, y, test_size=0.33, random_state=42, shuffle=False
)
rf = RandomForestRegressor()
rf.fit(X_train, y_train)
pred_train = rf.predict(X_train)
plt.figure(figsize=(50,8))
plt.plot(y_train)
plt.plot(pred_train)
plt.show()

pred_test = rf.predict(X_test)
plt.figure(figsize=(50,8))
plt.plot(y_test.reset_index(drop=True))
plt.plot(pred_test)
plt.show()

Come previsto, si perde molta precisione nel set di test rispetto al set di allenamento. Questo potrebbe essere migliorato, ma nel complesso, le previsioni sembrano ragionevoli, anche se spesso conservative per quanto riguarda i valori molto alti.

print("MAPE è", round(mean_absolute_percentage_error(y_test,pred_test) * 100, 2), "%")

MAPE è 17.16 %

Modello Senza Dati Meteorologici

Per confermare che l’aggiunta dei dati meteorologici ha migliorato il modello, confrontiamolo con un modello di riferimento che viene addestrato su tutto tranne che sui dati meteorologici:

X = d[
    [
        "day_of_week", 
        "hour", 
        "holiday_today", 
        "holiday_tomorrow", 
        "holiday_yesterday"
    ]
]
y = d["count"] 
X_train, X_test, y_train, y_test = train_test_split(
  X, y, test_size=0.33, random_state=42, shuffle=False
)
rf0 = RandomForestRegressor(random_state=42)
rf0.fit(X_train, y_train)
pred_train = rf0.predict(X_train)
pred_test = rf0.predict(X_test)
print("MAPE è", round(mean_absolute_percentage_error(y_test,pred_test) * 100, 2), "%")

MAPE è 17,76%

L’aggiunta dei dati meteorologici ha migliorato il MAPE della previsione dei taxi di 0,6%. Sebbene questa percentuale possa sembrare poco significativa, a seconda delle operazioni di un’azienda, tale miglioramento potrebbe avere un impatto significativo.

Importanza delle caratteristiche

Oltre alle metriche, diamo un’occhiata all’importanza delle caratteristiche. Utilizzeremo il pacchetto SHAP, che utilizza i valori SHAP per spiegare il contributo individuale e marginale di ciascuna caratteristica al modello, ovvero controlla quanto una caratteristica individuale contribuisce rispetto alle altre caratteristiche.

explainer = shap.Explainer(rf)
shap_values = explainer(X_test)

Ci vorranno un paio di minuti, poiché esegue molti scenari “cosa succederebbe se” su tutte le caratteristiche: se mancasse una caratteristica, come influenzerebbe l’accuratezza complessiva della previsione?

shap.plots.beeswarm(shap_values)

Possiamo vedere che di gran lunga le variabili esplicative più importanti sono state l’ora del giorno e il giorno della settimana. Ha perfetto senso. Il conteggio dei taxi è altamente ciclico, con una forte variazione della domanda di taxi durante il giorno e la settimana. Alcuni dei dati meteorologici si sono rivelati utili anche. Quando fa freddo, ci sono più corse in taxi. In qualche misura, però, la temperatura potrebbe anche essere un proxy per gli effetti generali della stagionalità annuale sulla domanda di taxi. Un’altra caratteristica importante sono le raffiche di vento, con meno taxi utilizzati quando ci sono più raffiche. Un’ipotesi potrebbe essere che ci sia meno traffico durante il maltempo.

Ulteriori miglioramenti al modello

  • Valutare la creazione di ulteriori caratteristiche dai dati esistenti, ad esempio ritardare la variabile target dal giorno o dalla settimana precedente.
  • Un frequente riallenamento del modello garantisce che le tendenze siano sempre catturate. Ciò avrà un grande impatto quando si utilizza il modello nel mondo reale.
  • Valutare l’aggiunta di ulteriori dati esterni, come il traffico e la congestione di NY.
  • Considerare altri modelli e strumenti per le serie temporali, come Facebook Prophet.
di Clint Patterson su Unsplash

Conclusione

Ecco fatto! Hai creato un modello semplice che utilizza i dati meteorologici e può essere utilizzato nella pratica.

In questo articolo abbiamo discusso dell’importanza dei dati meteorologici nei modelli di previsione in vari settori, delle sfide associate al loro utilizzo efficace e dei modelli e dei fornitori di previsioni meteorologiche numeriche disponibili, evidenziando BlueSky API come un modo economico ed efficiente per ottenere previsioni sia in tempo reale che storiche. Attraverso uno studio di caso sulle previsioni delle corse in taxi a New York, questo articolo fornisce una dimostrazione pratica dell’utilizzo dei dati meteorologici nell’apprendimento automatico, insegnandoti tutte le competenze di base necessarie per iniziare:

  • Passaggi tipici di ETL e creazione di caratteristiche per dati di serie temporali
  • ETL dei dati meteorologici e creazione di caratteristiche tramite BlueSky API
  • Adattamento e valutazione di un semplice modello di random forest per le serie temporali
  • Valutazione delle importanze delle caratteristiche utilizzando i valori SHAP

Punti chiave

  1. Sebbene i dati meteorologici possano essere estremamente complessi da integrare nei modelli di apprendimento automatico esistenti, i moderni servizi di dati meteorologici come BlueSky API riducono notevolmente il carico di lavoro.
  2. L’integrazione dei dati meteorologici di BlueSky nel modello ha migliorato l’accuratezza delle previsioni nello studio di caso sui taxi di New York, evidenziando che il tempo atmosferico svolge un ruolo pratico visibile nelle operazioni quotidiane.
  3. Molti settori come il commercio al dettaglio, l’agricoltura, l’energia, il trasporto, ecc. traggono vantaggio in modi simili o maggiori e richiedono quindi buone integrazioni di previsioni meteorologiche per migliorare le proprie previsioni e migliorare l’efficienza operativa e l’allocazione delle risorse.

Domande frequenti

I media mostrati in questo articolo non sono di proprietà di Analytics Vidhya e sono utilizzati a discrezione dell’autore.