
Motivazione: Come persona che lavora con dati panel, spesso ho bisogno di eseguire una convalida incrociata. Ciò comporta l'addestramento fino a un certo punto nel tempo, il test su un sottoinsieme di osservazioni, l'addestramento fino a un ulteriore momento nel tempo, il test su un diverso sottoinsieme di osservazioni e la continuazione iterativa di questo processo su un set di dati panel. Suona familiare? Può essere davvero frustrante implementarlo manualmente. Per semplificare le cose, ho creato un pacchetto chiamato Pannello diviso che può aiutare quando si lavora con i dati del pannello.
Questo articolo mostra come utilizzare PanelSplit quando si lavora con i dati del pannello; dall'ingegneria delle funzionalità, all'ottimizzazione degli iperparametri, alla generazione di previsioni, PanelSplit è qui per aiutarti!
Cosa sono i dati panel?
Di dati del pannelloIntendo dati in cui sono presenti più entità nel tempo. Queste entità potrebbero essere paesi, persone, organizzazioni o qualsiasi altra unità di analisi. Nel corso del tempo vengono registrate più osservazioni per queste molteplici entità.
Cos'è la convalida incrociata?
Supponiamo di voler ottenere stime della validità delle nostre previsioni quando utilizziamo un modello. Come possiamo farlo? L'approccio standard è convalida incrociatache prevede la suddivisione dei dati in pieghe successive, ciascuna con il proprio set di training e test unico. La visualizzazione seguente mostra come appare per i dati delle serie temporali.
Mentre esiste già una funzione scikit-learn per eseguire la convalida incrociata delle serie temporali chiamata TimeSeriesSplitnon funziona con i dati del pannello. Invece di essere una singola serie temporale per un’entità, i dati panel hanno più entità e abbiamo bisogno di uno strumento che ci permetta di lavorare con più entità.
È qui che entra in gioco PanelSplit. Pannello diviso è un pacchetto che ci permette di generalizzare TimeSeriesSplit ai dati del pannello. Offre anche funzionalità per la trasformazione, la previsione e molto altro, ma in questo articolo introduttivo tratterò solo le nozioni di base.
Ora che abbiamo introdotto cosa sono i dati del panel e come appare la convalida incrociata in questa impostazione, vediamo come eseguire la convalida incrociata utilizzando PanelSplit.
Innanzitutto, generiamo alcuni dati di esempio con cui lavorare:
import pandas as pd
import numpy as np# generate example data
num_countries = 3
years = range(2000, 2005)
num_years = len(years)
data = {
'country_id': (c for c in range(1, num_countries + 1) for _ in years),
'year': (year for _ in range(num_countries) for year in years),
'y': np.random.normal(0, 1, num_countries * num_years),
'x1': np.random.normal(0, 1, num_countries * num_years),
'x2': np.random.normal(0, 1, num_countries * num_years)
}
panel_data = pd.DataFrame(data)
# display the generated panel data
display(panel_data)
Dopo aver generato il set di dati del nostro panel, ora possiamo applicare PanelSplit.
Inizializzazione di PanelSplit
Quando inizializziamo PanelSplit, definiamo l'approccio di convalida incrociata che utilizzeremo.
- IL periodi l'argomento prende la serie temporale. In questo caso la serie è la colonna dell'anno.
- n_split, spaccoE prova_dimensione sono tutti gli argomenti utilizzati da TimeSeriesSplit per suddividere le serie temporali.
- Specificando trama=Veroviene prodotta una visualizzazione che descrive il treno e i set di test all'interno di ciascuna divisione.
!pip install panelsplit
from panelsplit import PanelSplitpanel_split = PanelSplit(periods = panel_data.year, n_splits = 3, gap = 0, test_size=1, plot=True)
Capire come funziona PanelSplit
Per avere un'idea migliore di come appaiono le divisioni, utilizziamo il file diviso() funzione per restituire i diversi set di training e test per ogni suddivisione.
splits = panel_split.split()
L'oggetto splits contiene le 3 suddivisioni della procedura di convalida incrociata. All'interno di ciascuna suddivisione è presente un elenco composto dagli indici train (il primo elemento) e dagli indici test (il secondo elemento). Gli indici sono valori Vero e Falso, che indicano se una riga si trova o meno in un particolare set di treni/test per una particolare suddivisione. Questi indici possono essere utilizzati per filtrare diversi sottoinsiemi di dati, come mostrato nella figura seguente.
Ottimizzazione degli iperparametri
Ora che abbiamo creato un'istanza di PanelSplit, facciamone alcune ottimizzazione degli iperparametri!
Qui eseguiamo una ricerca di iperparametri di base con un modello Ridge, specificando l'argomento cv per GridSearchCV essere panel_split. Durante la procedura di adattamento di GridSearchCV chiama la funzione split() di panel_split, restituendo gli indici per ogni treno e testando per ogni divisione. Utilizza questi indici per filtrare i dati forniti come argomenti X e y nella funzione fit().
from sklearn.linear_model import Ridge
from sklearn.model_selection import GridSearchCVparam_grid = {'alpha':(.1, .5)} # define the hyper-parameter grid space
# define the gridsearch and call fit, specifying panel_split for the cv argument
gridsearch = GridSearchCV(estimator = Ridge(), param_grid=param_grid, cv=panel_split)
gridsearch.fit(X = panel_data(('x1','x2')), y = panel_data('y'))
print(gridsearch.best_params_)
Evviva! Abbiamo trovato l'insieme ottimale di iperparametri. Ora possiamo usarli per fare previsioni.
Nota: in un ambiente reale distingueremo tra il set di test utilizzato per l'ottimizzazione degli iperparametri e il set di test utilizzato per valutare le prestazioni, ma per questo esempio manteniamo gli stessi set di convalida e set di test.
Generazione di previsioni con cross_val_fit_predict
Generare previsioni è davvero semplice con PanelSplit.
Utilizzando cross_val_fit_predictspecifichiamo che vogliamo utilizzare il nostro miglior modello Ridge, i nostri X e y e PanelSplit si adatterà a ciascun set di allenamento e prevederà ogni set di test, per ogni divisione.
predictions, models = panel_split.cross_val_fit_predict(estimator = Ridge(gridsearch.best_params_),
X = panel_data(('x1','x2')),
y = panel_data('y'))
Vengono restituite le previsioni e i modelli adattati. Se vogliamo includere gli identificatori per le previsioni, possiamo generare etichette utilizzando gen_test_labels e quindi creare una nuova serie Panda nel nostro dataframe predics_df.
predictions_df = panel_split.gen_test_labels(panel_data(('country_id','year')))
predictions_df('y_pred') = y_pred
display(predictions_df)
Questa è solo una demo di base, ma PanelSplit può fare molto di più! Per esempio:
- Con cross_val_fit_transform possiamo adattarci ai set di allenamento e trasformarci nei set di prova. Se mancano funzionalità che necessitano di imputazione, questo è davvero utile.
- Cosa succede se vogliamo ridimensionare i dati e ogni suddivisione necessita della propria “istantanea” dei dati per mantenere separate le trasformazioni di ridimensionamento? Possiamo usare gen_snapshots per fare questo! Oppure utilizza una pipeline scikit-learn come stimatore in cross_val_fit_predict 🙂
- Cosa succede se ci manca un periodo di tempo? Utilizzando il periodi unici discussione con il drop_split argomento al momento dell'inizializzazione, PanelSplit può gestirlo ed eliminare le suddivisioni dove non sono presenti osservazioni.
Se vuoi vedere altri esempi e vuoi provare PanelSplit in prima persona, dai un'occhiata al Taccuino di Giove Ho creato dove copro alcune funzionalità aggiuntive.
Questo è il primo pacchetto che ho scritto, quindi ho imparato molto lavorando su questo progetto. Grazie per aver letto e spero che PanelSplit ti aiuti nel tuo prossimo progetto di dati panel!
Nota: se non diversamente specificato, tutte le immagini sono dell'autore.
Fonte: towardsdatascience.com