Merge pull request #297 from robertopauletto/main
Italian translation - Chapter 7 completedpull/299/head
commit
f544d2aac8
@ -0,0 +1,185 @@
|
||||
# Introduzione alla previsione delle serie temporali
|
||||
|
||||
![Riepilogo delle serie temporali in uno sketchnote](../../../sketchnotes/ml-timeseries.png)
|
||||
|
||||
> Sketchnote di [Tomomi Imura](https://www.twitter.com/girlie_mac)
|
||||
|
||||
In questa lezione e nella successiva si imparerà qualcosa sulla previsione delle serie temporali, una parte interessante e preziosa del repertorio di uno scienziato ML che è un po' meno conosciuta rispetto ad altri argomenti. La previsione delle serie temporali è una sorta di "sfera di cristallo": sulla base delle prestazioni passate di una variabile come il prezzo, è possibile prevederne il valore potenziale futuro.
|
||||
|
||||
[![Introduzione alla previsione delle serie temporali](https://img.youtube.com/vi/cBojo1hsHiI/0.jpg)](https://youtu.be/cBojo1hsHiI "Introduzione alla previsione delle serie temporali")
|
||||
|
||||
> 🎥 Fare clic sull'immagine sopra per un video sulla previsione delle serie temporali
|
||||
|
||||
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/41/)
|
||||
|
||||
È un campo utile e interessante con un valore reale per il business, data la sua applicazione diretta a problemi di prezzi, inventario e problemi della catena di approvvigionamento. Mentre le tecniche di deep learning hanno iniziato a essere utilizzate per acquisire maggiori informazioni per prevedere meglio le prestazioni future, la previsione delle serie temporali rimane un campo ampiamente informato dalle tecniche classiche di ML.
|
||||
|
||||
> Un utile programma di studio delle serie temporali di Penn State può essere trovato [qui](https://online.stat.psu.edu/stat510/lesson/1)
|
||||
|
||||
## Introduzione
|
||||
|
||||
Si supponga di mantenere una serie di parchimetri intelligenti che forniscono dati su quanto spesso vengono utilizzati e per quanto nel corso del tempo.
|
||||
|
||||
> Se si potesse prevedere, in base alle prestazioni passate del contatore, il suo valore futuro secondo le leggi della domanda e dell'offerta?
|
||||
|
||||
Prevedere con precisione quando agire per raggiungere il proprio obiettivo è una sfida che potrebbe essere affrontata dalla previsione delle serie temporali. Non renderebbe le persone felici di pagare di più nei periodi di punta quando cercano un parcheggio, ma sarebbe un modo sicuro per generare entrate per pulire le strade!
|
||||
|
||||
Si esplorano alcuni dei tipi di algoritmi di serie temporali e si avvia un notebook per pulire e preparare alcuni dati. I dati che saranno analizzati sono tratti dal concorso di previsione GEFCom2014. Consiste in 3 anni di carico orario di elettricità e valori di temperatura tra il 2012 e il 2014. Dati i modelli storici del carico elettrico e della temperatura, è possibile prevedere i valori futuri del carico elettrico.
|
||||
|
||||
In questo esempio si imparerà a fare previsioni un passo avanti, utilizzando solo i dati di caricamento storici. Prima di iniziare, però, è utile capire cosa succede dietro le quinte.
|
||||
|
||||
## Definizioni
|
||||
|
||||
Quando si incontra il termine "serie temporale" è necessario comprenderne l'uso in diversi contesti.
|
||||
|
||||
🎓 **Serie temporali**
|
||||
|
||||
In matematica, "una serie temporale è una serie di punti dati indicizzati (o elencati o rappresentati graficamente) in ordine temporale". Più comunemente, una serie temporale è una sequenza presa in punti successivi equidistanti nel tempo. Un esempio di una serie temporale è il valore di chiusura giornaliero del [Dow Jones Industrial Average](https://it.wikipedia.org/wiki/Serie_storica). L'uso di grafici di serie temporali e modelli statistici si riscontra frequentemente nell'elaborazione del segnale, nelle previsioni meteorologiche, nella previsione dei terremoti e in altri campi in cui si verificano eventi e i punti dati possono essere tracciati nel tempo.
|
||||
|
||||
🎓 **Analisi delle serie temporali**
|
||||
|
||||
L'analisi delle serie temporali è l'analisi dei dati delle serie temporali sopra menzionati. I dati delle serie temporali possono assumere forme distinte, comprese le "serie temporali interrotte" che rilevano i modelli nell'evoluzione di una serie temporale prima e dopo un evento di interruzione. Il tipo di analisi necessaria per le serie temporali dipende dalla natura dei dati. I dati delle serie temporali possono assumere la forma di serie di numeri o caratteri.
|
||||
|
||||
L'analisi da eseguire utilizza una varietà di metodi, tra cui dominio della frequenza e dominio del tempo, lineare e non lineare e altro ancora. Per [saperne di più](https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc4.htm) sui molti modi per analizzare questo tipo di dati.
|
||||
|
||||
🎓 **Previsione delle serie temporali**
|
||||
|
||||
La previsione delle serie temporali è l'uso di un modello per prevedere i valori futuri in base ai modelli visualizzati dai dati raccolti in precedenza così come si sono verificati in passato. Sebbene sia possibile utilizzare modelli di regressione per esplorare i dati delle serie temporali, con indici temporali come x variabili su un grafico, tali dati vengono analizzati al meglio utilizzando tipi speciali di modelli.
|
||||
|
||||
I dati delle serie temporali sono un elenco di osservazioni ordinate, a differenza dei dati che possono essere analizzati mediante regressione lineare. Il più comune è ARIMA, acronimo che sta per "Autoregressive Integrated Moving Average" (Modello autoregressivo integrato a media mobile).
|
||||
|
||||
[I modelli ARIMA](https://online.stat.psu.edu/stat510/lesson/1/1.1) "mettono in relazione il valore attuale di una serie con i valori passati e gli errori di previsione passati". Sono più appropriati per l'analisi dei dati nel dominio del tempo, in cui i dati sono ordinati nel tempo.
|
||||
|
||||
> Esistono diversi tipi di modelli ARIMA, [qui](https://people.duke.edu/~rnau/411arim.htm) si possono trovare ulteriori informazioni al riguardo e di cui si parlerà nella prossima lezione.
|
||||
|
||||
Nella prossima lezione, si creerà un modello ARIMA utilizzando [Serie Temporali UYnivariate](https://itl.nist.gov/div898/handbook/pmc/section4/pmc44.htm), che si concentra su una variabile che cambia il suo valore nel tempo. Un esempio di questo tipo di dati è [questo insieme di dati](https://itl.nist.gov/div898/handbook/pmc/section4/pmc4411.htm) che registra la concentrazione mensile di C02 presso l'Osservatorio di Mauna Loa:
|
||||
|
||||
| CO2 | YearMonth | Year | Month |
|
||||
| :----: | :-------: | :---: | :---: |
|
||||
| 330.62 | 1975.04 | 1975 | 1 |
|
||||
| 331.40 | 1975.13 | 1975 | 2 |
|
||||
| 331.87 | 1975.21 | 1975 | 3 |
|
||||
| 333.18 | 1975.29 | 1975 | 4 |
|
||||
| 333.92 | 1975.38 | 1975 | 5 |
|
||||
| 333.43 | 1975.46 | 1975 | 6 |
|
||||
| 331.85 | 1975.54 | 1975 | 7 |
|
||||
| 330.01 | 1975.63 | 1975 | 8 |
|
||||
| 328.51 | 1975.71 | 1975 | 9 |
|
||||
| 328.41 | 1975.79 | 1975 | 10 |
|
||||
| 329.25 | 1975.88 | 1975 | 11 |
|
||||
| 330.97 | 1975.96 | 1975 | 12 |
|
||||
|
||||
✅ Identificare la variabile che cambia nel tempo in questo set di dati
|
||||
|
||||
## [Caratteristiche dei dati](https://online.stat.psu.edu/stat510/lesson/1/1.1) delle serie temporali da considerare
|
||||
|
||||
Quando si esaminano i dati delle serie temporali, è possibile notare che presentano determinate caratteristiche che è necessario prendere in considerazione e mitigare per comprenderne meglio i modelli. Se si considerano i dati delle serie temporali come potenziali produttori di un "segnale" che si desidera analizzare, queste caratteristiche possono essere considerate "rumore". Spesso sarà necessario ridurre questo "rumore" compensando alcune di queste caratteristiche utilizzando alcune tecniche statistiche.
|
||||
|
||||
Ecco alcuni concetti che si dovrebbe conoscere per poter lavorare con le serie temporali:
|
||||
|
||||
🎓 **Tendenze**
|
||||
|
||||
Le tendenze sono definite come aumenti e diminuzioni misurabili nel tempo. [Per saperne di più](https://machinelearningmastery.com/time-series-trends-in-python). Nel contesto delle serie temporali, si tratta di come utilizzare e, se necessario, rimuovere le tendenze dalle serie temporali.
|
||||
|
||||
🎓 **[Stagionalità](https://machinelearningmastery.com/time-series-seasonality-with-python/)**
|
||||
|
||||
La stagionalità è definita come fluttuazioni periodiche, come le vacanze estive che potrebbero influire sulle vendite, ad esempio. [Si dia un'occhiata](https://itl.nist.gov/div898/handbook/pmc/section4/pmc443.htm) a come i diversi tipi di grafici mostrano la stagionalità nei dati.
|
||||
|
||||
🎓 **Valori anomali**
|
||||
|
||||
I valori anomali sono molto lontani dalla varianza dei dati standard.
|
||||
|
||||
🎓 **Ciclo di lunga durata**
|
||||
|
||||
Indipendentemente dalla stagionalità, i dati potrebbero mostrare un ciclo di lungo periodo come una recessione economica che dura più di un anno.
|
||||
|
||||
🎓 **Varianza costante**
|
||||
|
||||
Nel tempo, alcuni dati mostrano fluttuazioni costanti, come il consumo energetico giornaliero e notturno.
|
||||
|
||||
🎓 **Cambiamenti improvvisi**
|
||||
|
||||
I dati potrebbero mostrare un cambiamento improvviso che potrebbe richiedere un'ulteriore analisi. La brusca chiusura delle attività a causa del COVID, ad esempio, ha causato cambiamenti nei dati.
|
||||
|
||||
✅ Ecco un [esempio di grafico della serie temporale](https://www.kaggle.com/kashnitsky/topic-9-part-1-time-series-analysis-in-python) che mostra la valuta di gioco giornaliera spesa in alcuni anni. Si riesce a identificare una delle caratteristiche sopra elencate in questi dati?
|
||||
|
||||
![Spesa in valuta di gioco](../images/currency.png)
|
||||
|
||||
## Esercizio: iniziare con i dati sul consumo energetico
|
||||
|
||||
Si inizia a creare un modello di serie temporali per prevedere l'utilizzo futuro di energia dato l'utilizzo passato.
|
||||
|
||||
> I dati in questo esempio sono presi dal concorso di previsione GEFCom2014. Consiste in 3 anni di carico orario di elettricità e valori di temperatura tra il 2012 e il 2014.
|
||||
>
|
||||
> Tao Hong, Pierre Pinson, Shu Fan, Hamidreza Zareipour, Alberto Troccoli e Rob J. Hyndman, "Probabilistic energy forecasting: Global Energy Forecasting Competition 2014 and beyond", International Journal of Forecasting, vol.32, no.3, pp 896- 913, luglio-settembre 2016.
|
||||
|
||||
1. Nella cartella `working` di questa lezione, aprire il _file_ notebook.ipynb. Iniziare aggiungendo librerie che aiuteranno a caricare e visualizzare i dati
|
||||
|
||||
```python
|
||||
import os
|
||||
import matplotlib.pyplot as plt
|
||||
from common.utils import load_data
|
||||
%matplotlib inline
|
||||
```
|
||||
|
||||
Nota, si stanno utilizzando i file dalla cartella `common` inclusa che configura il proprio ambiente e gestisce il download dei dati.
|
||||
|
||||
2. Quindi, si esaminano i dati come un dataframe chiamando `load_data()` e `head()`:
|
||||
|
||||
```python
|
||||
data_dir = './data'
|
||||
energy = load_data(data_dir)[['load']]
|
||||
energy.head()
|
||||
```
|
||||
|
||||
Si può vedere che ci sono due colonne che rappresentano data e carico:
|
||||
|
||||
| | load |
|
||||
| :-----------------: | :----: |
|
||||
| 2012-01-01 00:00:00 | 2698.0 |
|
||||
| 2012-01-01 01:00:00 | 2558.0 |
|
||||
| 2012-01-01 02:00:00 | 2444.0 |
|
||||
| 2012-01-01 03:00:00 | 2402.0 |
|
||||
| 2012-01-01 04:00:00 | 2403.0 |
|
||||
|
||||
3. Ora, tracciare i dati chiamando `plot()`:
|
||||
|
||||
```python
|
||||
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![grafico dell'energia](../images/energy-plot.png)
|
||||
|
||||
4. Ora, tracciare la prima settimana di luglio 2014, fornendola come input per `energy` nella forma `[from date]: [to date]`:
|
||||
|
||||
```python
|
||||
energy['2014-07-01':'2014-07-07'].plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![luglio](../images/july-2014.png)
|
||||
|
||||
Uno stupendo grafico! Dare un'occhiata a questi grafici e vedere se si riesce a determinare una delle caratteristiche sopra elencate. Cosa si può dedurre visualizzando i dati?
|
||||
|
||||
Nella prossima lezione, si creerà un modello ARIMA per creare alcune previsioni.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Sfida
|
||||
|
||||
Fare un elenco di tutti i settori e le aree di indagine che vengono in mente che potrebbero trarre vantaggio dalla previsione delle serie temporali. Si riesce a pensare a un'applicazione di queste tecniche nelle arti? In Econometria? Ecologia? Vendita al Dettaglio? Industria? Finanza? Dove se no?
|
||||
|
||||
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/42/)
|
||||
|
||||
## Revisione e Auto Apprendimento
|
||||
|
||||
Sebbene non si tratteranno qui, le reti neurali vengono talvolta utilizzate per migliorare i metodi classici di previsione delle serie temporali. Si legga di più su di loro [in questo articolo](https://medium.com/microsoftazure/neural-networks-for-forecasting-financial-and-economic-time-series-6aca370ff412)
|
||||
|
||||
## Compito
|
||||
|
||||
[Visualizzare altre serie temporali](assignment.it.md)
|
@ -0,0 +1,11 @@
|
||||
# Visualizzare altre serie temporali
|
||||
|
||||
## Istruzioni
|
||||
|
||||
Si è iniziato a conoscere la previsione di serie temporali esaminando il tipo di dati richiesti da questa modellazione speciale. Si sono visualizzati alcuni dati sull'energia. Ora, cercare altri dati che potrebbero trarre vantaggio dalla previsione di serie temporali. Trovare tre esempi (provare [Kaggle](https://kaggle.com) e [Azure Open Datasets](https://azure.microsoft.com/en-us/services/open-datasets/catalog/?WT.mc_id=academic-15963-cxa)) e creare un notebook per visualizzarli. Annotare nel notebook tutte le caratteristiche speciali che hanno (stagionalità, cambiamenti improvvisi o altre tendenze).
|
||||
|
||||
## Rubrica
|
||||
|
||||
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
|
||||
| -------- | ------------------------------------------------------ | ---------------------------------------------------- | ----------------------------------------------------------------------------------------- |
|
||||
| | Tre insiemi di dati sono tracciati e spiegati in un notebook | Due insiemi di dati sono tracciati e spiegati in un notebook | Pochi insiemi di dati sono tracciati o spiegati in un notebook o i dati presentati sono insufficienti |
|
@ -0,0 +1,394 @@
|
||||
# Previsione delle serie temporali con ARIMA
|
||||
|
||||
Nella lezione precedente, si è imparato qualcosa sulla previsione delle serie temporali e si è caricato un insieme di dati che mostra le fluttuazioni del carico elettrico in un periodo di tempo.
|
||||
|
||||
[![Introduzione ad ARIMA](https://img.youtube.com/vi/IUSk-YDau10/0.jpg)](https://youtu.be/IUSk-YDau10 " Introduzione ad ARIMA")
|
||||
|
||||
> 🎥 Fare clic sull'immagine sopra per un video: Una breve introduzione ai modelli ARIMA. L'esempio è fatto in linguaggio R, ma i concetti sono universali.
|
||||
|
||||
## [Quiz Pre-Lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/43/)
|
||||
|
||||
## Introduzione
|
||||
|
||||
In questa lezione si scoprirà un modo specifico per costruire modelli con [ARIMA: *AutoRegressive Integrated Moving Average*](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average) (Media mobile integrata autoregressiva). I modelli ARIMA sono particolarmente indicati per l'adattamento di dati che mostrano [non stazionarietà](https://it.wikipedia.org/wiki/Processo_stazionario).
|
||||
|
||||
## Concetti generali
|
||||
|
||||
Per poter lavorare con ARIMA, ci sono alcuni concetti da conoscere:
|
||||
|
||||
- 🎓 **Stazionarietà**. In un contesto statistico, la stazionarietà si riferisce a dati la cui distribuzione non cambia se spostata nel tempo. I dati non stazionari, poi, mostrano fluttuazioni dovute a andamenti che devono essere trasformati per essere analizzati. La stagionalità, ad esempio, può introdurre fluttuazioni nei dati e può essere eliminata mediante un processo di "differenziazione stagionale".
|
||||
|
||||
- 🎓 **[Differenziazione](https://wikipedia.org/wiki/Autoregressive_integrated_moving_average#Differencing)**. I dati differenzianti, sempre in un contesto statistico, si riferiscono al processo di trasformazione dei dati non stazionari per renderli stazionari rimuovendo il loro andamento non costante. "La differenziazione rimuove le variazioni di livello di una serie temporale, eliminando tendenza e stagionalità e stabilizzando di conseguenza la media delle serie temporali." [Documento di Shixiong e altri](https://arxiv.org/abs/1904.07632)
|
||||
|
||||
## ARIMA nel contesto delle serie temporali
|
||||
|
||||
Si esaminano le parti di ARIMA per capire meglio come aiuta a modellare le serie temporali e a fare previsioni contro di esso.
|
||||
|
||||
- **AR - per AutoRegressivo**. I modelli autoregressivi, come suggerisce il nome, guardano "indietro" nel tempo per analizzare i valori precedenti nei dati e fare ipotesi su di essi. Questi valori precedenti sono chiamati "ritardi". Un esempio potrebbero essere i dati che mostrano le vendite mensili di matite. Il totale delle vendite di ogni mese sarebbe considerato una "variabile in evoluzione" nell'insieme di dati. Questo modello è costruito come "la variabile di interesse in evoluzione è regredita sui propri valori ritardati (cioè precedenti)". [wikipedia](https://it.wikipedia.org/wiki/Modello_autoregressivo_a_media_mobile)
|
||||
|
||||
- **I - per integrato**. A differenza dei modelli simili "ARMA", la "I" in ARIMA si riferisce al suo aspetto *[integrato](https://wikipedia.org/wiki/Order_of_integration)* . I dati vengono "integrati" quando vengono applicati i passaggi di differenziazione in modo da eliminare la non stazionarietà.
|
||||
|
||||
- **MA - per Media Mobile**. L'aspetto della [media mobile](https://it.wikipedia.org/wiki/Modello_a_media_mobile) di questo modello si riferisce alla variabile di output che è determinata osservando i valori attuali e passati dei ritardi.
|
||||
|
||||
In conclusione: ARIMA viene utilizzato per adattare il più possibile un modello alla forma speciale dei dati delle serie temporali.
|
||||
|
||||
## Esercizio: costruire un modello ARIMA
|
||||
|
||||
Aprire la cartella _/working_ in questa lezione e trovare il file _notebook.ipynb_.
|
||||
|
||||
1. Eseguire il notebook per caricare la libreria Python `statsmodels`; servirà per i modelli ARIMA.
|
||||
|
||||
1. Caricare le librerie necessarie
|
||||
|
||||
1. Ora caricare molte altre librerie utili per tracciare i dati:
|
||||
|
||||
```python
|
||||
import os
|
||||
import warnings
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import datetime as dt
|
||||
import math
|
||||
|
||||
from pandas.plotting import autocorrelation_plot
|
||||
from statsmodels.tsa.statespace.sarimax import SARIMAX
|
||||
from sklearn.preprocessing import MinMaxScaler
|
||||
from common.utils import load_data, mape
|
||||
from IPython.display import Image
|
||||
|
||||
%matplotlib inline
|
||||
pd.options.display.float_format = '{:,.2f}'.format
|
||||
np.set_printoptions(precision=2)
|
||||
warnings.filterwarnings("ignore") # specificare per ignorare messaggi di avvertimento
|
||||
```
|
||||
|
||||
1. Caricare i dati dal file `/data/energy.csv` in un dataframe Pandas e dare un'occhiata:
|
||||
|
||||
```python
|
||||
energy = load_data('./data')[['load']]
|
||||
energy.head(10)
|
||||
```
|
||||
|
||||
1. Tracciare tutti i dati energetici disponibili da gennaio 2012 a dicembre 2014. Non dovrebbero esserci sorprese poiché questi dati sono stati visti nell'ultima lezione:
|
||||
|
||||
```python
|
||||
energy.plot(y='load', subplots=True, figsize=(15, 8), fontsize=12)
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
Ora si costruisce un modello!
|
||||
|
||||
### Creare insiemi di dati di addestramento e test
|
||||
|
||||
Ora i dati sono stati caricati, quindi si possono separare in insiemi di addestramento e test. Si addestrerà il modello sull'insieme di addestramento. Come al solito, dopo che il modello ha terminato l'addestramento, se ne valuterà l'accuratezza utilizzando l'insieme di test. È necessario assicurarsi che l'insieme di test copra un periodo successivo dall'insieme di addestramento per garantire che il modello non ottenga informazioni da periodi di tempo futuri.
|
||||
|
||||
1. Assegnare un periodo di due mesi dal 1 settembre al 31 ottobre 2014 all'insieme di addestramento. L'insieme di test comprenderà il bimestre dal 1 novembre al 31 dicembre 2014:
|
||||
|
||||
```python
|
||||
train_start_dt = '2014-11-01 00:00:00'
|
||||
test_start_dt = '2014-12-30 00:00:00'
|
||||
```
|
||||
|
||||
Poiché questo dato riflette il consumo giornaliero di energia, c'è un forte andamento stagionale, ma il consumo è più simile al consumo nei giorni più recenti.
|
||||
|
||||
1. Visualizzare le differenze:
|
||||
|
||||
```python
|
||||
energy[(energy.index < test_start_dt) & (energy.index >= train_start_dt)][['load']].rename(columns={'load':'train'}) \
|
||||
.join(energy[test_start_dt:][['load']].rename(columns={'load':'test'}), how='outer') \
|
||||
.plot(y=['train', 'test'], figsize=(15, 8), fontsize=12)
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![Addestrare e testare i dati](../images/train-test.png)
|
||||
|
||||
Pertanto, l'utilizzo di una finestra di tempo relativamente piccola per l'addestramento dei dati dovrebbe essere sufficiente.
|
||||
|
||||
> Nota: poiché la funzione utilizzata per adattare il modello ARIMA usa la convalida nel campione durante l'adattamento, si omettono i dati di convalida.
|
||||
|
||||
### Preparare i dati per l'addestramento
|
||||
|
||||
Ora è necessario preparare i dati per l'addestramento eseguendo il filtraggio e il ridimensionamento dei dati. Filtrare l'insieme di dati per includere solo i periodi di tempo e le colonne che servono e il ridimensionamento per garantire che i dati siano proiettati nell'intervallo 0,1.
|
||||
|
||||
1. Filtrare l'insieme di dati originale per includere solo i suddetti periodi di tempo per insieme e includendo solo la colonna necessaria "load" più la data:
|
||||
|
||||
```python
|
||||
train = energy.copy()[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']]
|
||||
test = energy.copy()[energy.index >= test_start_dt][['load']]
|
||||
|
||||
print('Training data shape: ', train.shape)
|
||||
print('Test data shape: ', test.shape)
|
||||
```
|
||||
|
||||
Si può vedere la forma dei dati:
|
||||
|
||||
```output
|
||||
Training data shape: (1416, 1)
|
||||
Test data shape: (48, 1)
|
||||
```
|
||||
|
||||
1. Ridimensionare i dati in modo che siano nell'intervallo (0, 1).
|
||||
|
||||
```python
|
||||
scaler = MinMaxScaler()
|
||||
train['load'] = scaler.fit_transform(train)
|
||||
train.head(10)
|
||||
```
|
||||
|
||||
1. Visualizzare i dati originali rispetto ai dati in scala:
|
||||
|
||||
```python
|
||||
energy[(energy.index >= train_start_dt) & (energy.index < test_start_dt)][['load']].rename(columns={'load':'original load'}).plot.hist(bins=100, fontsize=12)
|
||||
train.rename(columns={'load':'scaled load'}).plot.hist(bins=100, fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![originale](../images/original.png)
|
||||
|
||||
> I dati originali.
|
||||
|
||||
![scaled](../images/scaled.png)
|
||||
|
||||
> I dati in scala
|
||||
|
||||
1. Ora che si è calibrato i dati scalati, si possono scalare i dati del test:
|
||||
|
||||
```python
|
||||
test['load'] = scaler.transform(test)
|
||||
test.head()
|
||||
```
|
||||
|
||||
### Implementare ARIMA
|
||||
|
||||
È tempo di implementare ARIMA! Si utilizzerà ora la libreria `statsmodels` installata in precedenza.
|
||||
|
||||
Ora occorre seguire diversi passaggi
|
||||
|
||||
1. Definire il modello chiamando `SARIMAX()` passando i parametri del modello: parametri p, d e q e parametri P, D e Q.
|
||||
2. Preparare il modello per i dati di addestramento chiamando la funzione fit().
|
||||
3. Effettuare previsioni chiamando la funzione `forecast()` specificando il numero di passaggi (l'orizzonte - `horizon`) da prevedere.
|
||||
|
||||
> 🎓 A cosa servono tutti questi parametri? In un modello ARIMA ci sono 3 parametri che vengono utilizzati per aiutare a modellare gli aspetti principali di una serie temporale: stagionalità, tendenza e rumore. Questi parametri sono:
|
||||
|
||||
`p`: il parametro associato all'aspetto autoregressivo del modello, che incorpora i valori *passati*.
|
||||
`d`: il parametro associato alla parte integrata del modello, che incide sulla quantità di *differenziazione* (🎓 si ricorda la differenziazione 👆?) da applicare a una serie temporale.
|
||||
`q`: il parametro associato alla parte a media mobile del modello.
|
||||
|
||||
> Nota: se i dati hanno un aspetto stagionale, come questo, si utilizza un modello ARIMA stagionale (SARIMA). In tal caso è necessario utilizzare un altro insieme di parametri: `P`, `D` e `Q` che descrivono le stesse associazioni di `p`, `d` e `q` , ma corrispondono alle componenti stagionali del modello.
|
||||
|
||||
1. Iniziare impostando il valore di orizzonte preferito. Si prova 3 ore:
|
||||
|
||||
```python
|
||||
# Specificare il numero di passaggi per prevedere in anticipo
|
||||
HORIZON = 3
|
||||
print('Forecasting horizon:', HORIZON, 'hours')
|
||||
```
|
||||
|
||||
La selezione dei valori migliori per i parametri di un modello ARIMA può essere difficile in quanto è in qualche modo soggettiva e richiede molto tempo. Si potrebbe prendere in considerazione l'utilizzo di una funzione `auto_arima()` dalla [libreria `pyramid`](https://alkaline-ml.com/pmdarima/0.9.0/modules/generated/pyramid.arima.auto_arima.html),
|
||||
|
||||
1. Per ora provare alcune selezioni manuali per trovare un buon modello.
|
||||
|
||||
```python
|
||||
order = (4, 1, 0)
|
||||
seasonal_order = (1, 1, 0, 24)
|
||||
|
||||
model = SARIMAX(endog=train, order=order, seasonal_order=seasonal_order)
|
||||
results = model.fit()
|
||||
|
||||
print(results.summary())
|
||||
```
|
||||
|
||||
Viene stampata una tabella dei risultati.
|
||||
|
||||
Si è costruito il primo modello! Ora occorre trovare un modo per valutarlo.
|
||||
|
||||
### Valutare il modello
|
||||
|
||||
Per valutare il modello, si può eseguire la cosiddetta convalida `walk forward` . In pratica, i modelli di serie temporali vengono riaddestrati ogni volta che diventano disponibili nuovi dati. Ciò consente al modello di effettuare la migliore previsione in ogni fase temporale.
|
||||
|
||||
A partire dall'inizio della serie temporale utilizzando questa tecnica, addestrare il modello sull'insieme di dati di addestramento Quindi fare una previsione sul passaggio temporale successivo. La previsione viene valutata rispetto al valore noto. L'insieme di addestramento viene quindi ampliato per includere il valore noto e il processo viene ripetuto.
|
||||
|
||||
> Nota: è necessario mantenere fissa la finestra dell'insieme di addestramento per un addestramento più efficiente in modo che ogni volta che si aggiunge una nuova osservazione all'insieme di addestramento, si rimuove l'osservazione dall'inizio dell'insieme.
|
||||
|
||||
Questo processo fornisce una stima più solida di come il modello si comporterà in pratica. Tuttavia, ciò comporta il costo computazionale della creazione di così tanti modelli. Questo è accettabile se i dati sono piccoli o se il modello è semplice, ma potrebbe essere un problema su larga scala.
|
||||
|
||||
La convalida walk-forward è lo standard di riferimento per valutazione del modello di serie temporali ed è consigliata per i propri progetti.
|
||||
|
||||
1. Innanzitutto, creare un punto dati di prova per ogni passaggio HORIZON.
|
||||
|
||||
```python
|
||||
test_shifted = test.copy()
|
||||
|
||||
for t in range(1, HORIZON):
|
||||
test_shifted['load+'+str(t)] = test_shifted['load'].shift(-t, freq='H')
|
||||
|
||||
test_shifted = test_shifted.dropna(how='any')
|
||||
test_shifted.head(5)
|
||||
```
|
||||
|
||||
| | | load | load 1 | load 2 |
|
||||
| ---------- | -------- | ---- | ------ | ------ |
|
||||
| 2014/12/30 | 00:00:00 | 0,33 | 0.29 | 0,27 |
|
||||
| 2014/12/30 | 00:01:00:00 | 0.29 | 0,27 | 0,27 |
|
||||
| 2014/12/30 | 02:00:00 | 0,27 | 0,27 | 0,30 |
|
||||
| 2014/12/30 | 03:00:00 | 0,27 | 0,30 | 0.41 |
|
||||
| 2014/12/30 | 04:00 | 0,30 | 0.41 | 0,57 |
|
||||
|
||||
I dati vengono spostati orizzontalmente in base al loro punto horizon.
|
||||
|
||||
1. Fare previsioni sui dati di test utilizzando questo approccio a finestra scorrevole in un ciclo della dimensione della lunghezza dei dati del test:
|
||||
|
||||
```python
|
||||
%%time
|
||||
training_window = 720 # dedicare 30 giorni (720 ore) for l'addestramento
|
||||
|
||||
train_ts = train['load']
|
||||
test_ts = test_shifted
|
||||
|
||||
history = [x for x in train_ts]
|
||||
history = history[(-training_window):]
|
||||
|
||||
predictions = list()
|
||||
|
||||
order = (2, 1, 0)
|
||||
seasonal_order = (1, 1, 0, 24)
|
||||
|
||||
for t in range(test_ts.shape[0]):
|
||||
model = SARIMAX(endog=history, order=order, seasonal_order=seasonal_order)
|
||||
model_fit = model.fit()
|
||||
yhat = model_fit.forecast(steps = HORIZON)
|
||||
predictions.append(yhat)
|
||||
obs = list(test_ts.iloc[t])
|
||||
# move the training window
|
||||
history.append(obs[0])
|
||||
history.pop(0)
|
||||
print(test_ts.index[t])
|
||||
print(t+1, ': predicted =', yhat, 'expected =', obs)
|
||||
```
|
||||
|
||||
Si può guardare l'addestramento in corso:
|
||||
|
||||
```output
|
||||
2014-12-30 00:00:00
|
||||
1 : predicted = [0.32 0.29 0.28] expected = [0.32945389435989236, 0.2900626678603402, 0.2739480752014323]
|
||||
|
||||
2014-12-30 01:00:00
|
||||
2 : predicted = [0.3 0.29 0.3 ] expected = [0.2900626678603402, 0.2739480752014323, 0.26812891674127126]
|
||||
|
||||
2014-12-30 02:00:00
|
||||
3 : predicted = [0.27 0.28 0.32] expected = [0.2739480752014323, 0.26812891674127126, 0.3025962399283795]
|
||||
```
|
||||
|
||||
1. Confrontare le previsioni con il carico effettivo:
|
||||
|
||||
```python
|
||||
eval_df = pd.DataFrame(predictions, columns=['t+'+str(t) for t in range(1, HORIZON+1)])
|
||||
eval_df['timestamp'] = test.index[0:len(test.index)-HORIZON+1]
|
||||
eval_df = pd.melt(eval_df, id_vars='timestamp', value_name='prediction', var_name='h')
|
||||
eval_df['actual'] = np.array(np.transpose(test_ts)).ravel()
|
||||
eval_df[['prediction', 'actual']] = scaler.inverse_transform(eval_df[['prediction', 'actual']])
|
||||
eval_df.head()
|
||||
```
|
||||
|
||||
```output
|
||||
| | | timestamp | h | prediction | actual |
|
||||
| --- | ---------- | --------- | --- | ---------- | -------- |
|
||||
| 0 | 2014-12-30 | 00:00:00 | t+1 | 3,008.74 | 3,023.00 |
|
||||
| 1 | 2014-12-30 | 01:00:00 | t+1 | 2,955.53 | 2,935.00 |
|
||||
| 2 | 2014-12-30 | 02:00:00 | t+1 | 2,900.17 | 2,899.00 |
|
||||
| 3 | 2014-12-30 | 03:00:00 | t+1 | 2,917.69 | 2,886.00 |
|
||||
| 4 | 2014-12-30 | 04:00:00 | t+1 | 2,946.99 | 2,963.00 |
|
||||
```
|
||||
|
||||
Osservare la previsione dei dati orari, rispetto al carico effettivo. Quanto è accurato questo?
|
||||
|
||||
### Controllare la precisione del modello
|
||||
|
||||
Controllare l'accuratezza del modello testando il suo errore percentuale medio assoluto (MAPE) su tutte le previsioni.
|
||||
|
||||
> **🧮 Mostrami la matematica!**
|
||||
>
|
||||
> ![MAPE (%)](../images/mape.png)
|
||||
>
|
||||
> [MAPE](https://www.linkedin.com/pulse/what-mape-mad-msd-time-series-allameh-statistics/) viene utilizzato per mostrare l'accuratezza della previsione come un rapporto definito dalla formula qui sopra. La differenza tra actual<sub>t</sub> e predicted<sub>t</sub> viene divisa per actual<sub>t</sub>. "Il valore assoluto in questo calcolo viene sommato per ogni punto nel tempo previsto e diviso per il numero di punti adattati n." [wikipedia](https://wikipedia.org/wiki/Mean_absolute_percentage_error)
|
||||
|
||||
1. Equazione espressa in codice:
|
||||
|
||||
```python
|
||||
if(HORIZON > 1):
|
||||
eval_df['APE'] = (eval_df['prediction'] - eval_df['actual']).abs() / eval_df['actual']
|
||||
print(eval_df.groupby('h')['APE'].mean())
|
||||
```
|
||||
|
||||
1. Calcolare il MAPE di un passo:
|
||||
|
||||
```python
|
||||
print('One step forecast MAPE: ', (mape(eval_df[eval_df['h'] == 't+1']['prediction'], eval_df[eval_df['h'] == 't+1']['actual']))*100, '%')
|
||||
```
|
||||
|
||||
Previsione a un passo MAPE: 0,5570581332313952 %
|
||||
|
||||
1. Stampare la previsione a più fasi MAPE:
|
||||
|
||||
```python
|
||||
print('Multi-step forecast MAPE: ', mape(eval_df['prediction'], eval_df['actual'])*100, '%')
|
||||
```
|
||||
|
||||
```output
|
||||
Multi-step forecast MAPE: 1.1460048657704118 %
|
||||
```
|
||||
|
||||
Un bel numero basso è il migliore: si consideri che una previsione che ha un MAPE di 10 è fuori dal 10%.
|
||||
|
||||
1. Ma come sempre, è più facile vedere visivamente questo tipo di misurazione dell'accuratezza, quindi si traccia:
|
||||
|
||||
```python
|
||||
if(HORIZON == 1):
|
||||
## Tracciamento previsione passo singolo
|
||||
eval_df.plot(x='timestamp', y=['actual', 'prediction'], style=['r', 'b'], figsize=(15, 8))
|
||||
|
||||
else:
|
||||
## Tracciamento posizione passo multiplo
|
||||
plot_df = eval_df[(eval_df.h=='t+1')][['timestamp', 'actual']]
|
||||
for t in range(1, HORIZON+1):
|
||||
plot_df['t+'+str(t)] = eval_df[(eval_df.h=='t+'+str(t))]['prediction'].values
|
||||
|
||||
fig = plt.figure(figsize=(15, 8))
|
||||
ax = plt.plot(plot_df['timestamp'], plot_df['actual'], color='red', linewidth=4.0)
|
||||
ax = fig.add_subplot(111)
|
||||
for t in range(1, HORIZON+1):
|
||||
x = plot_df['timestamp'][(t-1):]
|
||||
y = plot_df['t+'+str(t)][0:len(x)]
|
||||
ax.plot(x, y, color='blue', linewidth=4*math.pow(.9,t), alpha=math.pow(0.8,t))
|
||||
|
||||
ax.legend(loc='best')
|
||||
|
||||
plt.xlabel('timestamp', fontsize=12)
|
||||
plt.ylabel('load', fontsize=12)
|
||||
plt.show()
|
||||
```
|
||||
|
||||
![un modello di serie temporale](../images/accuracy.png)
|
||||
|
||||
🏆 Un grafico molto bello, che mostra un modello con una buona precisione. Ottimo lavoro!
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Sfida
|
||||
|
||||
Scoprire i modi per testare l'accuratezza di un modello di serie temporali. Si esamina MAPE in questa lezione, ma ci sono altri metodi che si potrebbero usare? Ricercarli e annotarli. Un documento utile può essere trovato [qui](https://otexts.com/fpp2/accuracy.html)
|
||||
|
||||
## [Quiz post-lezione](https://jolly-sea-0a877260f.azurestaticapps.net/quiz/44/)
|
||||
|
||||
## Revisione e Auto Apprendimento
|
||||
|
||||
Questa lezione tratta solo le basi della previsione delle serie temporali con ARIMA. SI prenda del tempo per approfondire le proprie conoscenze esaminando [questo repository](https://microsoft.github.io/forecasting/) e i suoi vari tipi di modelli per imparare altri modi per costruire modelli di serie temporali.
|
||||
|
||||
## Compito
|
||||
|
||||
[Un nuovo modello ARIMA](assignment.it.md)
|
@ -0,0 +1,11 @@
|
||||
# Un nuovo modello ARIMA
|
||||
|
||||
## Istruzioni
|
||||
|
||||
Ora che si è creato un modello ARIMA, crearne uno nuovo con dati aggiornati (provare uno di [questi set di dati da Duke](http://www2.stat.duke.edu/~mw/ts_data_sets.html)). Annotare il lavoro in un notebook, visualizzare i dati e il modello e verificarne l'accuratezza utilizzando MAPE.
|
||||
|
||||
## Rubrica
|
||||
|
||||
| Criteri | Ottimo | Adeguato | Necessita miglioramento |
|
||||
| -------- | ------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ----------------------------------- |
|
||||
| | Viene presentato un notebook con un nuovo modello ARIMA costruito, testato e spiegato con visualizzazioni e accuratezza dichiarate. | Il notebook presentato non è annotato o contiene bug | Viene presentato un notebook incompleto |
|
@ -0,0 +1,22 @@
|
||||
# Introduzione alla previsione delle serie temporali
|
||||
|
||||
Che cos'è la previsione delle serie temporali? Si tratta di prevedere eventi futuri analizzando le tendenze del passato.
|
||||
|
||||
## Argomento regionale: consumo di elettricità in tutto il mondo ✨
|
||||
|
||||
In queste due lezioni, si verrà introdotti alla previsione delle serie temporali, un'area un po' meno conosciuta di machine learning che è tuttavia estremamente preziosa per l'industria e le applicazioni aziendali, tra gli altri campi. Sebbene le reti neurali possano essere utilizzate per migliorare l'utilità di questi modelli, verranno studiate nel contesto di machine learning classico come modelli che aiutano a prevedere le prestazioni future basandosi sul passato.
|
||||
|
||||
L'obiettivo regionale è l'utilizzo elettrico nel mondo, un interessante insieme di dati per conoscere la previsione del consumo energetico futuro in base ai modelli di carico passato. Si può vedere come questo tipo di previsione può essere estremamente utile in un ambiente aziendale.
|
||||
|
||||
![rete elettrica](../images/electric-grid.jpg)
|
||||
|
||||
Foto di <a href="https://unsplash.com/@shutter_log?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Peddi Sai hrithik</a> di torri elettriche su una strada in Rajasthan su <a href="https://unsplash.com/s/photos/electric-india?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>
|
||||
|
||||
## Lezioni
|
||||
|
||||
1. [Introduzione alla previsione delle serie temporali](../1-Introduction/translations/README.it.md)
|
||||
2. [Costruire modelli di serie temporali ARIMA](../2-ARIMA/translations/README.it.md)
|
||||
|
||||
## Crediti
|
||||
|
||||
"Introduzione alla previsione delle serie temporali" è stato scritto con ⚡️ da [Francesca Lazzeri](https://twitter.com/frlazzeri) e [Jen Looper](https://twitter.com/jenlooper)
|
Loading…
Reference in new issue