Come prevedere i dati delle serie temporali utilizzando qualsiasi modello di apprendimento supervisionato |  di Matthew Turk |  Febbraio 2024

 | Intelligenza-Artificiale

Presentare i dati delle serie temporali in un formato tabulare standard per i modelli ML classici e migliorare la precisione utilizzando AutoML

Fonte: Attore Ahasanara

Questo articolo approfondisce il miglioramento del processo di previsione dei livelli di consumo energetico giornaliero trasformando un set di dati di serie temporali in un formato tabellare utilizzando librerie open source. Esploriamo l’applicazione di un popolare modello di classificazione multiclasse e sfruttiamo AutoML con Cleanlab Studio per aumentare significativamente la nostra precisione fuori campione.

Il punto chiave di questo articolo è che possiamo utilizzare metodi più generali per modellare un set di dati di serie temporali convertendolo in una struttura tabellare e persino trovare miglioramenti nel tentativo di prevedere questi dati di serie temporali.

Ad alto livello:

  • Stabilisci una precisione di base adattando un modello di previsione del Profeta ai nostri dati di serie temporali
  • Converti i dati delle nostre serie temporali in un formato tabellare utilizzando librerie di caratterizzazione open source e poi mostreremo che può sovraperformare il nostro modello Prophet con un approccio di classificazione multiclasse standard (Gradient Boosting) mediante un Riduzione del 67% dell’errore di previsione (aumento del 38% di punti percentuali grezzi nell’accuratezza fuori campione).
  • Utilizza una soluzione AutoML per la classificazione multiclasse ha comportato una riduzione del 42% dell’errore di previsione (aumento dell’8% in punti percentuali grezzi nell’accuratezza fuori campione) rispetto al nostro modello Gradient Boosting e ha comportato una riduzione dell’81% dell’errore di previsione (aumento del 46% in punti percentuali grezzi nell’accuratezza fuori campione) rispetto al nostro modello di previsione Prophet.

Per eseguire il codice illustrato in questo articolo, ecco il file taccuino pieno.

È possibile scaricare il set di dati Qui.

I dati rappresentano il consumo energetico orario di PJM (in megawatt) su base oraria. PJM Interconnection LLC (PJM) è un’organizzazione di trasmissione regionale (RTO) negli Stati Uniti. Fa parte della rete di interconnessione orientale che gestisce un sistema di trasmissione elettrica che serve molti stati.

Diamo un’occhiata al nostro set di dati. I dati includono una colonna data/ora (object tipo) e il consumo di energia in megawatt (float64) tipo) colonna che stiamo cercando di prevedere come variabile discreta (corrispondente al quartile dei livelli di consumo energetico orario). Il nostro obiettivo è addestrare un modello di previsione di serie temporali per essere in grado di prevedere il livello di consumo energetico giornaliero di domani rientrando in 1 di 4 livelli: low , below average , above average O high (questi livelli sono stati determinati sulla base dei quartili della distribuzione complessiva dei consumi giornalieri). Per prima cosa dimostreremo come applicare metodi di previsione delle serie temporali come Prophet a questo problema, ma questi sono limitati a determinati tipi di modelli ML adatti ai dati delle serie temporali. Successivamente dimostreremo come riformulare questo problema in un problema di classificazione multiclasse standard a cui possiamo applicare qualsiasi modello di machine learning e mostreremo come possiamo ottenere previsioni superiori utilizzando un potente ML supervisionato.

Per prima cosa convertiamo questi dati in un consumo energetico medio a livello giornaliero e rinominiamo le colonne nel formato previsto dal modello di previsione di Prophet. Questi livelli di consumo energetico giornaliero in valore reale vengono convertiti in quartili, che è il valore che stiamo cercando di prevedere. I nostri dati di allenamento sono mostrati di seguito insieme al quartile in cui rientra ciascun livello di consumo energetico giornaliero. I quartili vengono calcolati utilizzando i dati di addestramento per evitare fughe di dati.

Mostriamo quindi i dati del test di seguito, ovvero i dati rispetto ai quali stiamo valutando i risultati delle nostre previsioni.

Dati di allenamento con quartile del livello di consumo energetico giornaliero inclusi

Mostriamo quindi i dati del test di seguito, ovvero i dati rispetto ai quali stiamo valutando i risultati delle nostre previsioni.

Dati di test con quartile del livello di consumo energetico giornaliero inclusi

Come visto nelle immagini sopra, utilizzeremo una data limite di 2015-04-09 per terminare l’intervallo dei nostri dati di addestramento e iniziare i dati di test a 2015-04-10 . Calcoliamo le soglie quartili del nostro consumo energetico giornaliero utilizzando SOLO i dati di allenamento. Ciò evita la perdita di dati, utilizzando dati fuori campione disponibili solo in futuro.

Successivamente, prevederemo il livello di consumo energetico giornaliero PJME (in MW) per la durata dei nostri dati di test e rappresenteremo i valori previsti come una variabile discreta. Questa variabile rappresenta il quartile in cui rientra il livello di consumo energetico giornaliero, rappresentato categoricamente come 1 (low), 2 (below average), 3 (above average), o 4 (high). Per la valutazione, utilizzeremo il file accuracy_score funzione da scikit-learn per valutare le prestazioni dei nostri modelli. Poiché stiamo formulando il problema in questo modo, siamo in grado di valutare le previsioni del nostro modello per il giorno successivo (e confrontare i modelli futuri) utilizzando l’accuratezza della classificazione.

import numpy as np
from prophet import Prophet
from sklearn.metrics import accuracy_score

# Initialize model and train it on training data
model = Prophet()
model.fit(train_df)

# Create a dataframe for future predictions covering the test period
future = model.make_future_dataframe(periods=len(test_df), freq='D')
forecast = model.predict(future)

# Categorize forecasted daily values into quartiles based on the thresholds
forecast('quartile') = pd.cut(forecast('yhat'), bins = (-np.inf) + list(quartiles) + (np.inf), labels=(1, 2, 3, 4))

# Extract the forecasted quartiles for the test period
forecasted_quartiles = forecast.iloc(-len(test_df):)('quartile').astype(int)

# Categorize actual daily values in the test set into quartiles
test_df('quartile') = pd.cut(test_df('y'), bins=(-np.inf) + list(quartiles) + (np.inf), labels=(1, 2, 3, 4))
actual_test_quartiles = test_df('quartile').astype(int)

# Calculate the evaluation metrics
accuracy = accuracy_score(actual_test_quartiles, forecasted_quartiles)

# Print the evaluation metrics
print(f'Accuracy: {accuracy:.4f}')
>>> 0.4249

La precisione fuori campione è piuttosto scarsa, pari al 43%. Modellando le nostre serie temporali in questo modo, ci limitiamo a utilizzare solo modelli di previsione delle serie temporali (un sottoinsieme limitato di possibili modelli ML). Nella sezione successiva, considereremo come possiamo modellare questi dati in modo più flessibile trasformando le serie temporali in un set di dati tabulari standard tramite un’adeguata caratterizzazione. Una volta che la serie temporale è stata trasformata in un set di dati tabulari standard, siamo in grado di utilizzare qualsiasi modello ML supervisionato per prevedere i dati sul consumo energetico giornaliero.

Ora convertiamo i dati delle serie temporali in un formato tabellare e presentiamo i dati utilizzando le librerie open source sktime, tsfreshE tsfel. Utilizzando librerie come queste, possiamo estrarre un’ampia gamma di funzionalità che catturano modelli e caratteristiche sottostanti dei dati delle serie temporali. Ciò include caratteristiche statistiche, temporali e possibilmente spettrali, che forniscono un’istantanea completa del comportamento dei dati nel tempo. Suddividendo le serie temporali in singole caratteristiche, diventa più semplice comprendere in che modo i diversi aspetti dei dati influenzano la variabile target.

TSFreshFeatureExtractor è uno strumento di estrazione di funzionalità da sktime libreria che sfrutta le capacità di tsfresh per estrarre caratteristiche rilevanti dai dati delle serie temporali. tsfresh è progettato per calcolare automaticamente un vasto numero di caratteristiche di serie temporali, che possono essere molto utili per comprendere dinamiche temporali complesse. Per il nostro caso d’uso, utilizziamo l’insieme minimo ed essenziale di funzionalità del nostro TSFreshFeatureExtractor per caratterizzare i nostri dati.

tsfelo Time Series Feature Extraction Library, offre una suite completa di strumenti per estrarre feature dai dati delle serie temporali. Utilizziamo una configurazione predefinita che consente di costruire un ricco insieme di caratteristiche (ad esempio statistiche, temporali, spettrali) a partire dai dati delle serie temporali del consumo energetico, catturando un’ampia gamma di caratteristiche che potrebbero essere rilevanti per il nostro compito di classificazione.

import tsfel
from sktime.transformations.panel.tsfresh import TSFreshFeatureExtractor

# Define tsfresh feature extractor
tsfresh_trafo = TSFreshFeatureExtractor(default_fc_parameters="minimal")

# Transform the training data using the feature extractor
X_train_transformed = tsfresh_trafo.fit_transform(X_train)

# Transform the test data using the same feature extractor
X_test_transformed = tsfresh_trafo.transform(X_test)

# Retrieves a pre-defined feature configuration file to extract all available features
cfg = tsfel.get_features_by_domain()

# Function to compute tsfel features per day
def compute_features(group):
# TSFEL expects a DataFrame with the data in columns, so we transpose the input group
features = tsfel.time_series_features_extractor(cfg, group, fs=1, verbose=0)
return features

# Group by the 'day' level of the index and apply the feature computation
train_features_per_day = X_train.groupby(level='Date').apply(compute_features).reset_index(drop=True)
test_features_per_day = X_test.groupby(level='Date').apply(compute_features).reset_index(drop=True)

# Combine each featurization into a set of combined features for our train/test data
train_combined_df = pd.concat((X_train_transformed, train_features_per_day), axis=1)
test_combined_df = pd.concat((X_test_transformed, test_features_per_day), axis=1)

Successivamente, puliamo il nostro set di dati rimuovendo le caratteristiche che mostravano un’elevata correlazione (superiore a 0,8) con la nostra variabile target (livelli medi di consumo energetico giornaliero) e quelle con correlazioni nulle. Le funzionalità ad alta correlazione possono portare a un overfitting, in cui il modello funziona bene sui dati di addestramento ma scarsamente sui dati invisibili. Le caratteristiche correlate a valori nulli, d’altro canto, non forniscono alcun valore in quanto mancano di una relazione definibile con l’obiettivo.

Escludendo queste funzionalità, miriamo a migliorare la generalizzabilità del modello e a garantire che le nostre previsioni siano basate su un insieme equilibrato e significativo di input di dati.

# Filter out features that are highly correlated with our target variable
column_of_interest = "PJME_MW__mean"
train_corr_matrix = train_combined_df.corr()
train_corr_with_interest = train_corr_matrix(column_of_interest)
null_corrs = pd.Series(train_corr_with_interest.isnull())
false_features = null_corrs(null_corrs).index.tolist()

columns_to_exclude = list(set(train_corr_with_interest(abs(train_corr_with_interest) > 0.8).index.tolist() + false_features))
columns_to_exclude.remove(column_of_interest)

# Filtered DataFrame excluding columns with high correlation to the column of interest
X_train_transformed = train_combined_df.drop(columns=columns_to_exclude)
X_test_transformed = test_combined_df.drop(columns=columns_to_exclude)

Se ora osserviamo le prime righe dei dati di addestramento, questa è un’istantanea di come appaiono. Ora disponiamo di 73 funzionalità aggiunte dalle librerie di caratterizzazione delle serie temporali che abbiamo utilizzato. L’etichetta che prevediamo in base a queste caratteristiche è il livello di consumo energetico del giorno successivo.

Prime 5 righe di dati di addestramento recentemente presentati e in formato tabellare

È importante notare che abbiamo utilizzato la procedura consigliata di applicare il processo di caratterizzazione separatamente per i dati di training e di test per evitare perdite di dati (e i dati di test conservati sono le nostre osservazioni più recenti).

Inoltre, calcoliamo il nostro valore quartile discreto (utilizzando i quartili originariamente definiti) utilizzando il seguente codice per ottenere le nostre etichette energetiche di treno/test, che sono le nostre y_labels.

# Define a function to classify each value into a quartile
def classify_into_quartile(value):
if value < quartiles(0):
return 1
elif value < quartiles(1):
return 2
elif value < quartiles(2):
return 3
else:
return 4

y_train = X_train_transformed("PJME_MW__mean").rename("daily_energy_level")
X_train_transformed.drop("PJME_MW__mean", inplace=True, axis=1)

y_test = X_test_transformed("PJME_MW__mean").rename("daily_energy_level")
X_test_transformed.drop("PJME_MW__mean", inplace=True, axis=1)

energy_levels_train = y_train.apply(classify_into_quartile)
energy_levels_test = y_test.apply(classify_into_quartile)

Utilizzando il nostro set di dati tabulari, possiamo applicare qualsiasi modello ML supervisionato per prevedere i futuri livelli di consumo energetico. Qui utilizzeremo un modello Gradient Boosting Classifier (GBC), l’arma preferita dalla maggior parte dei data scientist che operano su dati tabulari.

Il nostro modello GBC è istanziato da sklearn.ensemble modulo e configurato con iperparametri specifici per ottimizzarne le prestazioni ed evitare l’overfitting.

from sklearn.ensemble import GradientBoostingClassifier

gbc = GradientBoostingClassifier(
n_estimators=150,
learning_rate=0.1,
max_depth=4,
min_samples_leaf=20,
max_features='sqrt',
subsample=0.8,
random_state=42
)

gbc.fit(X_train_transformed, energy_levels_train)

y_pred_gbc = gbc.predict(X_test_transformed)
gbc_accuracy = accuracy_score(energy_levels_test, y_pred_gbc)
print(f'Accuracy: {gbc_accuracy:.4f}')
>>> 0.8075

La precisione fuori campione dell’81% è notevolmente migliore rispetto ai risultati del nostro modello Prophet precedente.

Ora che abbiamo visto come caratterizzare il problema delle serie temporali e i vantaggi dell’applicazione di potenti modelli ML come Gradient Boosting, emerge una domanda naturale: quale modello ML supervisionato dovremmo applicare? Naturalmente, potremmo sperimentare molti modelli, mettere a punto i loro iperparametri e metterli insieme. Una soluzione più semplice è lasciare che AutoML gestisca tutto questo per noi.

Qui utilizzeremo una semplice soluzione AutoML fornita in Studio CleanLabche implica una configurazione zero. Forniamo semplicemente il nostro set di dati tabulari e la piattaforma addestra automaticamente molti tipi di modelli ML supervisionati (incluso Gradient Boosting, tra gli altri), ottimizza i relativi iperparametri e determina quali modelli è meglio combinare in un unico predittore. Ecco tutto il codice necessario per addestrare e distribuire un classificatore supervisionato AutoML:


from cleanlab_studio import Studio

studio = Studio()
studio.create_project(
dataset_id=energy_forecasting_dataset,
project_name="ENERGY-LEVEL-FORECASTING",
modality="tabular",
task_type="multi-class",
model_type="regular",
label_column="daily_energy_level",
)

model = studio.get_model(energy_forecasting_model)
y_pred_automl = model.predict(test_data, return_pred_proba=True)

Di seguito possiamo vedere le stime di valutazione del modello nella piattaforma AutoML, che mostrano tutti i diversi tipi di modelli ML che sono stati adattati e valutati automaticamente (inclusi più modelli Gradient Boosting), nonché un predittore di insieme costruito combinando in modo ottimale le loro previsioni.

Risultati AutoML tra diversi tipi di modelli utilizzati

Dopo aver eseguito l’inferenza sui nostri dati di test per ottenere le previsioni del livello di consumo energetico del giorno successivo, vediamo che la precisione del test è dell’89%, un miglioramento dell’8% in punti percentuali grezzi rispetto al nostro precedente approccio Gradient Boosting.

Precisione del test AutoML sui dati relativi al livello di consumo energetico giornaliero

Per i nostri dati sul consumo energetico giornaliero PJM, abbiamo scoperto che trasformando i dati in un formato tabellare e mettendoli in evidenza si è ottenuto un risultato Riduzione del 67% dell’errore di previsione (aumento del 38% in punti percentuali grezzi nell’accuratezza fuori campione) rispetto alla nostra accuratezza di base stabilita con il nostro modello di previsione Prophet.

Abbiamo anche provato un semplice approccio AutoML per la classificazione multiclasse, che ha comportato una riduzione del 42% dell’errore di previsione (aumento dell’8% in punti percentuali grezzi nell’accuratezza fuori campione) rispetto al nostro modello Gradient Boosting e ha comportato una riduzione dell’81% dell’errore di previsione (aumento del 46% in punti percentuali grezzi nell’accuratezza fuori campione) rispetto al nostro modello di previsione Prophet.

Adottando approcci come quelli illustrati sopra per modellare un set di dati di serie temporali oltre l’approccio vincolato che prevede solo la considerazione dei metodi di previsione, possiamo applicare tecniche di ML supervisionate più generali e ottenere risultati migliori per determinati tipi di problemi di previsione.

Se non diversamente specificato, tutte le immagini sono dell’autore.

Fonte: towardsdatascience.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *