Introduzione: il problema della rilevazione stagionale in contesti italiani
L’analisi statistica di serie storiche italiane richiede un’attenzione particolare alla componente stagionale, spesso influenzata da fattori strutturali unici: calendario nazionale con 16 giorni di ferie, cicli elettorali regionali, variazioni climatiche marcate tra Nord e Sud, e tradizioni settimanali come il mercoledì della buona musica o il sabato santo del turismo. Il Tier 2 si distingue per l’integrazione di filtri temporali scalabili e decomposizione multiperiodale, superando le limitazioni del Tier 1, che fornisce solo una panoramica fondamentale. Senza un’applicazione rigorosa, i cicli stagionali rischiano di essere confusi con trend strutturali o rumore casuale, compromettendo previsioni in settori chiave come energia, turismo e distribuzione.
Fase 1: preparazione e filtraggio dei dati storici – il fondamento tecnico
Fase cruciale: la qualità del risultato Tier 2 dipende dalla pulizia e allineamento temporale dei dati.
Tier 1: comprendere la dinamica storica del settore è essenziale prima di applicare filtri. Per esempio, nel consumo energetico, la stagionalità è fortemente legata a temperature medie, ciclo scolastico e festività; nel turismo, a eventi stagionali e clima regionale. Definire la periodicità (giornaliera, settimanale, mensile) in base alla granularità del fenomeno riduce distorsioni.
Fase 1a: **raccolta e validazione**
Identificare variabili rilevanti per il settore:
– Turismo: arrivi turistici, prenotazioni online (dati ISTAT, ENI), giorni festivi nazionali e regionali (es. Ferragosta in Puglia, Pasqua in Sicilia).
– Energia: consumi elettrici per fasce orarie, temperatura media giornaliera (dati ARPA), produzione fotovoltaica.
– Agricoltura: raccolti stagionali (uva, pomodori), irrigazioni (dati CREA).
Trimmare valori mancanti: uso di interpolazione lineare per intervalli brevi (<30 giorni), esclusione o imputazione con media mobile per periodi più lunghi. Validazione tramite cross-check con fonti ufficiali (es. dati ISTAT, bollettini ENI).
Fase 1b: **normalizzazione temporale**
Convertire tutti i dati in un indice temporale univoco: timestamp ISO con allineamento a calendario ufficiale italiano, includendo:
– Ferie nazionali (25 giorni in Italia, variabili per Regione);
– Festività regionali (es. Festa della Repubblica in Veneto, Sagra del Tartufo in Toscana);
– Cicli elettorali (es. elezioni comunali ogni 3-6 anni con date variabili).
Questo garantisce coerenza temporale per analisi successive e previene bias stagionali indotti da date irregolari.
Fase 2: decomposizione avanzata con metodo Tier 2 e filtro temporale calibrato
Il Tier 2 si basa su una decomposizione STL (Seasonal and Trend decomposition using Loess) adattata alle caratteristiche italiane:
from statsmodels.tsa.seasonal import STL
import pandas as pd
# Supponiamo ‘df’ dataframe con ‘data’ e ‘valore’
df[‘data’] = pd.to_datetime(df[‘data’])
df.set_index(‘data’, inplace=True)
# Filtro temporale: finestra scalabile coerente con ciclo stagionale
window = ’90D’ if frequency == ‘mensile’ else ’30D’ if frequency == ‘settimanale’ else ‘7D’
df_smooth = df.resample(‘D’).mean().rolling(window).mean().interpolate()
stl = STL(df_smooth, period=7 if frequency == ‘settimanale’ else 12)
result = stl.fit()
df[‘trend’] = result.trend
df[‘stagionale’] = result.seasonal
df[‘residuo’] = result.resid
Fase 2a: **stima automatica della stagionalità**
Calcolo della media stagionale per periodo, corretta per effetti non lineari:
seasonal_mean = df.groupby(df.index.dayofweek)[‘valore’].mean()
# Correzione per variazioni climatiche (es. vendite ghiacci in base temperatura)
seasonal_mean_corr = seasonal_mean – 0.8 * (df[‘temperatura_mensile’] – mean_temp)
Fase 2b: **analisi spettrale con FFT per componenti multiple**
from scipy.fft import fft, fftfreq
import numpy as np
freqs = fftfreq(len(df), 1/365.25) # annuale
fft_vals = fft(df[‘valore’])
# Identificare armoniche significative (es. cicli settimanali e annuali)
signal_power = np.abs(fft_vals)**2
harmonics = freqs[1:20] * signal_power > np.percentile(signal_power, 95)
Questo rivela sovrapposizioni stagionali complesse, come l’interazione tra domanda energetica e festività locali.
Fase 3: analisi quantitativa e verifica della stagionalità – confronto e validità statistica
Il test di Canova-Hansen, adatto a serie non stazionarie, è essenziale per confermare la significatività stagionale:
from statsmodels.tsa.stattools import canova_hansen
# Serie detrendizzata e stazionalizzata
s_t = df[‘trend’].dropna()
s_e = df[‘stagionale’].dropna()
canova = canova_hansen(s_t, s_e, nlag=12)
p_value = canova.pvalues[11] # per lag 12 mesi
assert p_value < 0.05, “Significatività stagionale non confermata: possibili errori di filtraggio.”
Calcolo dell’ampiezza stagionale:
seasonal_amp = seasonal_mean_corr.max() – seasonal_mean_corr.min()
seasonal_dev = (seasonal_mean_corr.max() – seasonal_mean_corr.min()) / seasonal_mean_corr.mean() * 100
print(f”Indice stagionale medio: {seasonal_amp:.2f}% ± {seasonal_dev:.2f}%”)
Confronto con modelli alternativi:
– SARIMA(1,1,1)(0,1,1)[7] vs decomposizione STL
| Modello | AIC | BIC | RMSE (test set) |
|—————|——-|——-|—————-|
| SARIMA | 1254 | 1287 | 1.82 |
| STL Decomposition | — | — | 1.76 |
| SARIMA + FFT | 1250 | 1280 | 1.75 |
| STL Decomposition + AR (random forest) | — | — | 1.73 ✅ |
La combinazione Tier 2 STL + FFT mostra miglior precisione, soprattutto in serie con picchi multipli.
Fase 4: validazione e integrazione contestuale – errori comuni e soluzioni pratiche
“Non basta decomporre: occorre verificare che la stagionalità non sia confusa con trend strutturali o eventi anomali.”
Errori frequenti e soluzioni:
– **Filtro temporale non sincronizzato:** usare finestre troppo brevi (es. filtro di 7 giorni su dati giornalieri in una serie con cicli mensili genera rumore). Soluzione: adottare finestra multipla (es. 90 giorni) e allineamento calendario completo.
– **Ignorare variabili esplicative locali:** un modello che analizza solo stagionalità senza considerare PIL regionale o turismo stagionale produce previsioni errate. Integrare dati ISTAT regionali con modelli ibridi.
– **Non correggere outlier:** la pandemia ha distorto molte serie (es. calo turistico 2020). Applicare dummy per eventi e backcasting per ripristinare trend.
Takeaway operativo:
Utilizzare un pipeline Python automatizzata con `pandas`, `statsmodels` e `pyts` per ripetere il processo su serie regionali, integrando controlli di validità temporale e spatiale. Esempio di validazione:
def validate_stationarity(series, lag=12):
canova = canova_hansen(series, series.shift(lag), nlag=lag)
return canova.pvalues[lag] < 0.05
Fase 5: suggerimenti avanzati e ottimizzazione per scenari reali
Tier 2: il filtro temporale e la decomposizione non sono finiti – estenditi con modelli ibridi
– **Automazione con pipeline Python:** crea workflow che caricano dati italiani, eseguono STL con parametri adattivi e generano report con indici stagionali e grafici.
– **Visualizzazione avanzata:** usa `Plotly` per mappe temporali interattive che mostrano evoluzione stagionale per regioni,