I dati di serie temporali sono dati raccolti sullo stesso soggetto in momenti diversi, come il PIL di un paese per anno, il prezzo di un'azione di una particolare azienda in un certo periodo, o il tuo battito cardiaco registrato ogni secondo. Qualsiasi dato che puoi rilevare in modo continuo a intervalli di tempo diversi è una forma di dato di serie temporale.
Di seguito un esempio di dati di serie temporali che mostrano il numero di casi di COVID-19 negli Stati Uniti come riportato al CDC. L'asse x mostra il passare del tempo e l'asse y rappresenta il numero di casi di COVID-19 in migliaia.

I dataset più convenzionali che memorizzano informazioni in un singolo momento, come informazioni su clienti, prodotti e aziende, sono invece noti come dati trasversali (cross-sectional). Un esempio è mostrato nel dataset qui sotto, che traccia i paesi con il maggior numero di casi di COVID-19 in un periodo di tempo fisso e coerente per tutti i paesi.

Non è molto difficile distinguere la differenza tra dati trasversali e dati di serie temporali, dato che gli obiettivi di analisi sono ampiamente diversi. Nei nostri esempi, prima eravamo interessati a tracciare i casi di COVID-19 nel tempo, poi ad analizzare i casi per paese in un periodo fisso.
Un tipico dataset reale è probabilmente un ibrido di questi formati. Ad esempio, possiamo pensare a un rivenditore come Walmart che vende migliaia di prodotti ogni giorno. Se analizzi le vendite per prodotto in un determinato giorno, si tratta di un'analisi trasversale. Potresti voler scoprire qual è l'articolo più venduto la Vigilia di Natale, per esempio. Invece, se vuoi conoscere la vendita di un particolare articolo in un periodo di tempo (diciamo gli ultimi 5 anni), questa sarebbe un'analisi di serie temporali.
Gli obiettivi cambiano quando si analizzano dati di serie temporali rispetto a dati trasversali, e un dataset reale è spesso un ibrido di entrambi.
Cos'è il forecasting delle serie temporali?
Il forecasting delle serie temporali è esattamente ciò che sembra: prevedere valori sconosciuti. Consiste nel raccogliere dati storici, prepararli per essere utilizzati dagli algoritmi e quindi prevedere valori futuri in base ai pattern appresi dai dati storici.
Ci sono numerosi motivi per cui le aziende possono essere interessate a prevedere valori futuri, come PIL, vendite mensili, inventario, disoccupazione e temperature globali:
- Un rivenditore può essere interessato a prevedere le vendite future a livello di SKU (stock keeping unit) per pianificazione e budgeting.
- Un piccolo commerciante può voler prevedere le vendite per negozio, così da pianificare le giuste risorse (più persone nei periodi di maggiore affluenza e viceversa).
- Un colosso software come Google può voler conoscere l'ora più affollata della giornata o il giorno più trafficato della settimana per allocare di conseguenza le risorse dei server.
- Il dipartimento della salute può essere interessato a prevedere le vaccinazioni COVID cumulative somministrate, per stimare quando si raggiungerà l'immunità di gregge.
Tipi di forecasting delle serie temporali
Esistono tre tipi di forecasting per serie temporali. Quale usare dipende dal tipo di dati con cui stai lavorando e dal caso d'uso specifico:
Previsione univariata
Una serie temporale univariata, come suggerisce il nome, è una serie con una singola variabile dipendente dal tempo. Per esempio, se stai tracciando i valori di temperatura orari per una regione e vuoi prevedere la temperatura futura usando le temperature storiche, questa è una previsione univariata. I tuoi dati potrebbero apparire così:

Previsione multivariata
Al contrario, una serie temporale multivariata ha più di una variabile dipendente dal tempo. Ogni variabile dipende non solo dai propri valori passati ma anche da altre variabili. Questa dipendenza viene usata per prevedere i valori futuri.
Riprendendo l'esempio precedente, supponiamo che il nostro dataset includa altri attributi meteorologici nello stesso periodo, come percentuale di umidità, punto di rugiada, velocità del vento, ecc., insieme ai valori di temperatura. In questo caso, per prevedere in modo ottimale la temperatura vanno considerate più variabili. Una serie del genere rientra nella categoria delle serie temporali multivariate. Il tuo dataset ora apparirà così:

Stai comunque prevedendo i valori di temperatura per il futuro, ma ora puoi usare le altre informazioni disponibili nella tua previsione, assumendo che la temperatura dipenda anche da questi fattori.
Fonte immagine: Van Nguyen
Quando affrontiamo la previsione multivariata, le variabili in ingresso possono essere di due tipi:
- Esogene: variabili di input non influenzate da altre variabili di input e da cui dipende la variabile di output.
- Endogene: variabili di input influenzate da altre variabili di input e da cui dipende la variabile di output.
Questo tutorial tratterà diversi modelli classici, ma non tutti supportano la previsione multivariata. In queste situazioni, i modelli di machine learning vengono in aiuto, perché puoi modellare qualsiasi problema di forecasting come regressione. Vedremo un esempio più avanti.
Metodi di forecasting per serie temporali
Il forecasting delle serie temporali può essere ampiamente suddiviso nelle seguenti categorie:
- Modelli classici/statistici — Medie mobili, smoothing esponenziale, ARIMA, SARIMA, TBATS
- Machine learning — Regressione lineare, XGBoost, Random Forest, o qualsiasi modello ML con metodi di riduzione
- Deep learning — RNN, LSTM
Questo tutorial è focalizzato sui primi due metodi: modelli classici/statistici e machine learning. I metodi di deep learning sono fuori dallo scopo di questo tutorial.
Modelli statistici
Per il forecasting con modelli statistici, esistono diversi algoritmi popolari e consolidati. Ognuno ha proprietà matematiche diverse e un proprio set di assunzioni da rispettare. Questo tutorial non entrerà nel dettaglio matematico, ma ti darà un'intuizione che speriamo sia utile.
ARIMA
ARIMA è uno dei metodi classici più popolari per il forecasting delle serie temporali. Sta per autoregressive integrated moving average ed è un tipo di modello che prevede una serie temporale basandosi sui suoi stessi valori passati, cioè sui propri lag e sugli errori di previsione ritardati. ARIMA è composto da tre componenti:
- Autoregressione (AR): un modello in cui una variabile dipendente cambia in funzione dei propri valori ritardati.
- Integrato (I): rappresenta la differenziazione delle osservazioni grezze per rendere la serie stazionaria (ovvero i valori vengono sostituiti dalla differenza tra i valori e i valori precedenti).
- Media mobile (MA): incorpora la dipendenza tra un'osservazione e l'errore residuo di un modello a media mobile applicato alle osservazioni ritardate.
La parte "AR" di ARIMA indica che la variabile di interesse è regressa sui propri valori ritardati (cioè osservati in precedenza). La parte "MA" indica che l'errore di regressione è una combinazione lineare di termini d'errore i cui valori sono avvenuti contemporaneamente e in vari momenti del passato. La "I" (per "integrato") indica che i valori dei dati sono stati sostituiti dalla differenza rispetto ai valori precedenti (e questo processo può essere stato eseguito più volte). Lo scopo di ciascuna componente è far sì che il modello si adatti ai dati nel modo migliore possibile.
SARIMA
Un'estensione di ARIMA che supporta la modellazione diretta della componente stagionale della serie è chiamata SARIMA. Un problema di ARIMA è che non supporta dati stagionali, cioè serie con cicli ripetuti. ARIMA si aspetta dati non stagionali o con la componente stagionale rimossa, ad esempio con differenziazione stagionale. SARIMA aggiunge tre nuovi iperparametri per specificare autoregressione (AR), differenziazione (I) e media mobile (MA) per la componente stagionale della serie.
Previsione con modello SARIMA
Smoothing esponenziale
Lo smoothing esponenziale è un metodo di forecasting per dati univariati. Può essere esteso per supportare dati con trend o stagionalità. Può essere usato come alternativa alla famiglia ARIMA.
Lo smoothing esponenziale assegna pesi decrescenti in modo esponenziale dalle osservazioni più recenti a quelle più vecchie. Più i dati sono vecchi, minore è il peso; ai dati più recenti viene assegnato un peso maggiore.
- Lo smoothing esponenziale semplice usa una media mobile pesata con pesi decrescenti esponenzialmente.
- Lo smoothing esponenziale di Holt è solitamente più affidabile per gestire dati con trend.
- Lo smoothing esponenziale triplo (chiamato anche Holt-Winters moltiplicativo) è più affidabile per trend parabolici o per dati con trend e stagionalità.
confronto tra smoothing esponenziale semplice (ES), doppio ES e EWMA a due stadi
TBATS
I modelli TBATS sono pensati per serie temporali con stagionalità multiple. Ad esempio, i dati di vendita al dettaglio possono avere una struttura giornaliera e settimanale, oltre a una stagionale annuale.
In TBATS, si applica una trasformazione di Box-Cox alla serie originale, che viene poi modellata come combinazione lineare di un trend smussato esponenzialmente, una componente stagionale e una componente ARMA.
Previsione con TBATS
Machine learning
Se non vuoi usare modelli statistici o non danno buoni risultati, puoi provare questo approccio. Il machine learning è un modo alternativo per modellare dati di serie temporali ai fini del forecasting. In questo metodo, estraiamo feature dalla data da aggiungere alle nostre "variabili X" e il valore della serie temporale è la "variabile y". Vediamo un esempio:
Per questo tutorial ho usato il dataset dei passeggeri delle compagnie aeree statunitensi, scaricabile da Kaggle.
Esempio di dataset
Possiamo estrarre feature dalla colonna "Date" come mese, anno, settimana dell'anno, ecc. Ecco un esempio:
# extract month and year from dates
data['Month'] = [i.month for i in data['Date']]
data['Year'] = [i.year for i in data['Date']]
# create a sequence of numbers
data['Series'] = np.arange(1,len(data)+1)
# drop unnecessary columns and re-arrange
data.drop(['Date', 'MA12'], axis=1, inplace=True)
data = data[['Series', 'Year', 'Month', 'Passengers']]
# check the head of the dataset
data.head()
Righe di esempio dopo l'estrazione delle feature
Da notare che il train-test split per dati di serie temporali è particolare. Poiché non puoi cambiare l'ordine della tabella, devi assicurarti di non campionare casualmente: vuoi che i dati di test contengano punti futuri rispetto a quelli del train (il tempo scorre sempre in avanti).
# split data into train-test set
train = data[data['Year'] < 1960]
test = data[data['Year'] >= 1960]
# check shape
train.shape, test.shape
>>> ((132, 4), (12, 4))
Ora che abbiamo eseguito lo split, siamo pronti ad addestrare un modello di machine learning sui dati di train, valutarlo sui dati di test e misurarne le prestazioni. In questo esempio userò PyCaret, una libreria open-source low-code in Python che automatizza i workflow di machine learning. Per usare PyCaret, devi installarlo con pip.
# install pycaret
pip install pycaret
Se hai bisogno di aiuto durante l'installazione, fai riferimento alla documentazione ufficiale.
Supponendo che tu abbia installato PyCaret correttamente:
# import the regression module
from pycaret.regression import *
# initialize setup
s = setup(data = train, test_data = test, target = 'Passengers', fold_strategy = 'timeseries', numeric_features = ['Year', 'Series'], fold = 3, transform_target = True, session_id = 123)
Ora, per addestrare i modelli di machine learning, ti basta una riga:
best = compare_models(sort = 'MAE')
Output di compare_models
Il miglior modello con 3 fold cross-validation basata su Mean Absolute Error (MAE) è Leased Angle Regression. Possiamo ora usare questo modello per prevedere il futuro. Per farlo, dobbiamo creare le "variabili X" nel futuro. Si può fare generando date future ed estraendo da esse le feature.
Poiché abbiamo addestrato il modello fino al 1960, prevediamo cinque anni nel futuro fino al 1965. Per usare il modello finale e generare previsioni future, dobbiamo prima creare un dataset con le colonne Month, Year, Series sulle date future. Il codice seguente crea il dataset "X" futuro.
future_dates = pd.date_range(start = '1961-01-01', end = '1965-01-01', freq = 'MS')
future_df = pd.DataFrame()
future_df['Month'] = [i.month for i in future_dates]
future_df['Year'] = [i.year for i in future_dates]
future_df['Series'] = np.arange(145,(145+len(future_dates)))
future_df.head()
Righe di esempio da future_df
Ora possiamo usare future_df per fare previsioni:
predictions_future = predict_model(best, data=future_df)
predictions_future.head()
Output di predictions_future.head()
E ora possiamo tracciarle:
concat_df = pd.concat([data,predictions_future], axis=0)
concat_df_i = pd.date_range(start='1949-01-01', end = '1965-01-01', freq = 'MS')
concat_df.set_index(concat_df_i, inplace=True)
fig = px.line(concat_df, x=concat_df.index, y=["Passengers", "Label"], template = 'plotly_dark')
fig.show()
Passeggeri aerei USA effettivi (1949–1960) e previsti (1961–1964)
Ci sono alcuni elementi importanti da notare. Quando lavori con una serie univariata puoi sempre convertirla in un problema di regressione e risolverlo come in questo esempio. Tuttavia, devi fare attenzione alla cross-validation. Non puoi usare una cross-validation casuale sui modelli di serie temporali: devi usare tecniche appropriate per le serie. In questo esempio, PyCaret usa TimeSeriesSplit della libreria scikit-learn.
Framework Python per il forecasting
Facebook Prophet
Prophet è un software open-source rilasciato dal team Core Data Science di Facebook. È disponibile su CRAN e PyPI.
Prophet è una procedura per il forecasting di serie temporali basata su un modello additivo in cui i trend non lineari sono adattati con stagionalità annuale, settimanale e giornaliera, più gli effetti delle festività. Funziona al meglio con serie che hanno forti effetti stagionali e diversi cicli storici. Prophet è robusto ai dati mancanti e ai cambi di trend, e in genere gestisce bene gli outlier.
Per saperne di più, dai un'occhiata a questo link.
Previsione con FB Prophet
sktime
sktime è un framework open-source e unificato per il machine learning con serie temporali. Fornisce una piattaforma facile da usare, flessibile e modulare per un'ampia gamma di attività ML su serie temporali. Offre interfacce compatibili con scikit-learn e strumenti di composizione dei modelli, con l'obiettivo di rendere l'ecosistema più usabile e interoperabile.
Per saperne di più su sktime, consulta questo link.
pmdarima
Pmdarima è una libreria statistica progettata per colmare il vuoto nelle capacità di analisi delle serie temporali in Python. Include:
- L'equivalente della funzionalità auto.arima di R
- Una raccolta di test statistici di stazionarietà e stagionalità
- Scomposizioni stagionali di serie temporali
- Utility per la cross-validation
- Una ricca collezione di dataset di serie temporali integrati per prototipi ed esempi
Per saperne di più su pmdarima, consulta questa pagina.
Kats
Kats è un altro straordinario progetto open-source di Facebook, rilasciato dal loro team Infrastructure Data Science. È disponibile su PyPI.
Kats è un toolkit per analizzare dati di serie temporali; un framework leggero, facile da usare e generalizzabile per l'analisi delle serie temporali. Mira a fornire un punto unico per rilevamento, forecasting, estrazione/incorporamento di feature e analisi multivariata, ecc.
Previsione con KATS
Per saperne di più su KATS, dai un'occhiata a questo link.
Orbit
Orbit è un eccellente progetto open-source di Uber. È una libreria Python per il forecasting bayesiano di serie temporali. Fornisce un'interfaccia familiare e intuitiva initialize-fit-predict per i compiti su serie temporali, utilizzando linguaggi di programmazione probabilistica sotto il cofano.
Previsione con Orbit
Per saperne di più su Orbit, consulta questo link.
PyCaret
PyCaret è una libreria open-source low-code di machine learning in Python che automatizza i workflow di ML. Con PyCaret, passi meno tempo a scrivere codice e più tempo all'analisi. Puoi addestrare il modello, analizzarlo, iterare più velocemente che mai e distribuirlo all'istante come REST API o persino creare una semplice app ML front-end, tutto dal tuo Notebook preferito.
Architettura del modulo Time Series di PyCaret. Sviluppato dal Lead Developer Nikhil Gupta.
Di seguito vedremo un esempio end-to-end di forecasting su serie temporali usando la libreria PyCaret.
Esempio end-to-end
Il modulo time series di PyCaret è disponibile in beta, puoi scaricarlo con pip.
pip install pycaret-ts-alpha
Link a questo tutorial su Colab.
Dataset
Qui abbiamo usato il dataset airline, disponibile anche nel repository dati di PyCaret.
from pycaret.datasets import get_data
data = get_data('airlineer')

data.plot()

Setup dell'esperimento
Gli esperimenti in PyCaret iniziano con la funzione setup. Questa funzione si occupa di tutti i passaggi di preprocessing, train-test split, strategia di cross-validation e altre operazioni.
from pycaret.time_series import *
s = setup(data, session_id = 123)
Output della funzione setup
Exploratory Data Analysis (EDA)
Per l'EDA di una serie temporale univariata, ci sono alcune cose che puoi e dovresti fare.
Per l'uso di modelli classici e statistici, puoi eseguire alcuni test statistici. In PyCaret c'è una funzione che lo fa per te.
check_stats()
Output della funzione check_stats
Se stai lavorando con una serie univariata, puoi anche scomporla in trend, stagionalità ed errore per ulteriori analisi.
plot_model(plot = 'decomp_classical")
Output della funzione plot_model<c/entre> ## Addestramento e selezione del modello ## Per addestrare più modelli e selezionarne uno, ci basta una riga di codice. best = compare_models()
Output della funzione compare_models
PyCaret ha addestrato oltre 25 modelli usando una cross-validation adatta alle serie temporali e presenta un elenco di modelli in ordine decrescente di prestazioni. Il miglior modello in base a questo esperimento per questo dataset risulta essere lo smoothing esponenziale, con un mean absolute error di 7,781.
Analisi del modello
Prima di distribuire questo modello per generare previsioni future, possiamo visualizzare un paio di grafici per valutarne la qualità.
plot_model(best, plot = 'forecast', data_kwargs = {'fh': 24})
Grafico di forecasting della serie temporale
plot_model(best, plot = 'residuals')
Grafico dei residui della serie temporale
plot_model(best, plot = 'insample')
Grafico in-sample della serie temporale
Distribuzione del modello
A questo punto siamo pronti a finalizzare il modello e salvarlo per usi futuri.
# finalize model
final_best = finalize_model(best)
# save model
final_best = finalize_model(best)

Per ricaricare il file e generare previsioni su dati futuri:
# load model
loaded_model = load_model('my_best_model')
# generate predictions for the next 48 months
predict_model(loaded_model, fh = 48)
Output troncato
Conclusione
Il forecasting di serie temporali è un'abilità molto utile da imparare. Molti problemi reali sono di natura temporale. Le applicazioni spaziano su vari settori, con moltissimi casi pratici tra cui: previsioni meteo, economiche, sanitarie, finanziarie, retail, di business, studi ambientali, sociali e altro ancora.
In sostanza, qualsiasi dato storico con intervalli coerenti può essere analizzato con metodi di analisi delle serie temporali, portando a un compito di forecasting che apprende dai dati storici e cerca di prevedere il futuro. In conclusione, ci sono tre grandi categorie per il forecasting delle serie temporali:
- Modelli statistici - Smoothing esponenziale, ARIMA, SARIMA, TBATS, ecc.
- Machine learning - Regressione lineare, XGBoost, Random Forest, ecc.
- Deep learning - RNN, LSTM
Se vuoi approfondire conoscenze e competenze nel forecasting di serie temporali, dai un'occhiata a questo fantastico percorso "Time Series with Python" di Datacamp. In questo track imparerai a manipolare dati di serie temporali con pandas, lavorare con librerie statistiche come NumPy e statsmodels per analizzare i dati, e sviluppare le tue capacità di visualizzazione con Matplotlib, SciPy e seaborn. Alla fine, saprai come prevedere il futuro con i modelli della classe ARIMA e generare previsioni e insight con modelli di machine learning.

