Transformator de fuziune temporală: Prognoza serii temporale cu învățare profundă — Tutorial complet

Creați predicții precise și interpretabile

Creat cu DALLE [1]

Conform [2], Transformator de fuziune temporală depășește toate modelele proeminente de învățare profundă pentru prognoza serii de timp.

Inclusiv un prezentat Arborele de creștere a gradului model pentru datele serii temporale tabelare.

Dar ce este Transformator de fuziune temporală (TFT)[3] și de ce este atât de interesant?

În acest articol, vă explicăm pe scurt noutățile Transformator de fuziune temporală și construiți un proiect end-to-end pe Prognoza cererii de energie. Mai exact, vom acoperi:

  • Cum ne pregătim datele pentru formatul TFT.
  • Cum se construiește, se antrenează și se evaluează modelul TFT.
  • Cum să obțineți predicții privind datele de validare și predicții în afara eșantionului.
  • Cum se calculează importanțele caracteristicilor, modele de sezonalitate, și robustețea evenimentelor extreme folosind modelul încorporat atenție interpretabilă mecanism.

Să ne aruncăm cu capul!

Pentru o analiză aprofundată a arhitecturii Transformatorului de fuziune temporală, consultați-o anterior articol.

Temporal Fuziune Trăscumpărător (TFT) este un model bazat pe transformator care valorifică atenția personală pentru a capta dinamica temporală complexă a mai multor secvențe de timp.

TFT suportă:

  • Serii temporale multiple: Putem antrena un model TFT pe mii de serii de timp univariate sau multivariate.
  • Prognoza multi-orizont: Modelul produce predicții în mai mulți pași pentru una sau mai multe variabile țintă, inclusiv intervale de predicție.
  • Caracteristici eterogene: TFT acceptă multe tipuri de caracteristici, inclusiv variabile variabile în timp și variabile exogene statice.
  • Previziuni interpretabile: Predicțiile pot fi interpretate în termeni de importanță variabilă și de sezonalitate.

Una dintre aceste trăsături este unică Transformator de fuziune temporală. Vom acoperi acest lucru în secțiunea următoare.

Printre modelele notabile din seria de timp DL (de exemplu, DeepAR[4]), TFT se remarcă prin faptul că acceptă diverse tipuri de caracteristici. Acestea sunt:

  • Variază în timp cunoscut
  • Variază în timp necunoscut
  • Invariant în timp real
  • Invariant în timp categoric

De exemplu, imaginați-vă că avem un caz de prognoză a vânzărilor:

Să presupunem că trebuie să prezicem vânzările a 3 produse. The num sales este variabila țintă. The CPI index sau number of visitors sunt necunoscut care variază în timp caracteristici pentru că sunt cunoscute doar până în timpul predicției. In orice caz, holidaysși special days sunt cunoscute variabile în timp evenimente.

product id is un categoric invariant în timp (static). caracteristică. Alte caracteristici care sunt numerice și nu depind de timp, cum ar fi yearly_revenue poate fi clasificat ca real invariant în timp.

Înainte de a trece la proiectul nostru, vom arăta mai întâi un mini-tutorial despre cum să vă convertiți datele în format extins de serie temporală.

Notă: Toate imaginile și figurile din acest articol sunt create de autor.

Pentru acest tutorial, folosim TemporalFusionTransformer model din Prognoza PyTorch bibliotecă și PyTorch Lightning:

pip install torch pytorch-fulger pytorch_forecasting

Întregul proces implică 3 lucruri:

  1. Creați un cadru de date panda cu datele noastre din seria temporală.
  2. Împachetați cadrul nostru de date într-un TimeSeriesDataset instanță.
  3. Treci de noi TimeSeriesDataset exemplu pentru TemporalFusionTransformer.

TimeSeriesDataset este foarte util deoarece ne ajută să specificăm dacă caracteristicile variază în timp sau statice. În plus, este singurul format care TemporalFusionTransformer acceptă.

Să creăm un set minim de date de antrenament pentru a arăta cum TimeSeriesDataset lucrări:

Ar trebui să ne formatăm datele în felul următor: Fiecare casetă colorată reprezintă o serie temporală diferită, reprezentată de ea group valoare.

Figura 1: Cadrul de date sample_data panda

Cea mai importantă coloană a cadrului nostru de date este time_idx — determină succesiunea probelor. Dacă nu lipsesc observații, valorile ar trebui să crească cu +1 pentru fiecare serie temporală.

Apoi, împachetăm cadrul nostru de date într-un TimeSeriesDataset instanță:

Toate argumentele se explică de la sine: The max_encoder_length defineşte perioada de retrospectivă şi max_prediction_length specifică câte puncte de date vor fi prezise. În cazul nostru, ne uităm înapoi la 3 pași de timp în trecut pentru a scoate 2 predicții.

TimeSeriesDataset instanța servește acum ca încărcător de date. Să tipărim un lot și să verificăm cum vor fi transmise datele noastre către TFT:

Acest lot conține valorile de antrenament [0,1] din prima serie temporală (group 0) și valorile de testare[2,3,4]. Dacă executați din nou acest cod, veți obține valori diferite, deoarece datele sunt amestecate în mod implicit.

Proiectul nostru va folosi ElectricityLoadDiagrams20112014 [5] set de date de la UCI. Caietul pentru acest exemplu poate fi descărcat de pe aici:

Acest set de date conține consumul de energie (în KW) a 370 de clienți/consumatori cu o frecvență de 15 minute. Datele se întind pe 4 ani (2011-2014).

Unii consumatori au fost creați după 2011, astfel încât consumul lor de energie este inițial zero.

Facem preprocesare a datelor conform [3]:

  • Agregați variabila țintă power_usage pe oră.
  • Găsiți cea mai veche dată pentru fiecare serie de timp în care puterea este diferită de zero.
  • Creați funcții noi: month, day, hour și day_of_week.
  • Selectați toate zilele între 2014–01–01 și 2014–09–07.

Să începem:

Descărcați datele

wget https://archive.ics.uci.edu/ml/machine-learning-databases/00321/LD2011_2014.txt.zip
!unzip
LD2011_2014.txt.zip

Pre-procesare de date

Fiecare coloană reprezintă un consumator. Cele mai inițiale power_usage valorile sunt 0.

Apoi, cumulăm datele pe oră. Datorită dimensiunii și complexității modelului, antrenăm modelul nostru doar pe 5 consumatori (pentru cei cu valori diferite de zero).

Acum, ne pregătim setul de date pentru TimeSeriesDataset format. Observați că fiecare coloană reprezintă o serie temporală diferită. Prin urmare, ne „topim” cadrul de date, astfel încât toate seriile de timp să fie stivuite vertical în loc de orizontal. În acest proces, creăm noile noastre funcții.

Se apelează cadrul final de date preprocesat time_df. Să-i tipărim conținutul:

time_df este acum în formatul potrivit pentru TimeSeriesDataset. După cum ați ghicit până acum, deoarece granularitatea este pe oră, hours_from_start variabila va fi indice de timp.

Analiza datelor exploratorii

Alegerea a 5 consumatori/serie temporală nu este întâmplătoare. The power usage din fiecare serie temporală are proprietăți diferite, cum ar fi valoarea medie:

time_df[['consumer_id','power_usage']].groupby('consumer_id').mean()

Să diagramăm prima lună a fiecărei serii cronologice:

Figura 2: Prima lună din toate cele 5 serii cronologice/consumatori.

Nu există o tendință vizibilă, dar fiecare serie de timp are o sezonalitate și amplitudine ușor diferite. Putem experimenta și verifica în continuare staționaritatea, descompunerea semnalului și așa mai departe, dar în cazul nostru, ne concentrăm doar pe aspectul construcției modelului.

De asemenea, observați că alte metode de prognoză în serie de timp, cum ar fi ARIMA trebuie să îndeplinească câteva cerințe (de exemplu, seria temporală trebuie mai întâi să devină staționară.) Cu TFT, ne putem lăsa datele așa cum sunt.

Creați încărcătoare de date

În acest pas, ne trecem time_df la TimeSeriesDataSet format care este extrem de util deoarece:

  • Ne scutește de a scrie propriul nostru Dataloader.
  • Putem specifica modul în care TFT va gestiona caracteristicile setului de date.
  • Ne putem normaliza setul de date cu ușurință. În cazul nostru, normalizarea este obligatorie deoarece toate secvențele de timp diferă ca mărime. Astfel, folosim GroupNormalizer pentru a normaliza fiecare serie temporală în mod individual.

Modelul nostru folosește o fereastră de retrospectivă de o săptămână (7*24) pentru a estima consumul de energie în următoarele 24 de ore.

De asemenea, observați că hours_from_start este atât indicele de timp, cât și o caracteristică care variază în timp. The power_usage este variabila noastră țintă. De dragul demonstrației, setul nostru de validare este ultima zi:

Model de bază

În continuare, pasul pe care aproape toată lumea îl uită: un model de bază. În special în prognoza serii de timp, veți fi surprinși de cât de des un predictor naiv depășește chiar și un model mai bun!

Ca punct de referință naiv, prezicem curba de utilizare a energiei din ziua precedentă:

Antrenarea modelului de transformator de fuziune temporală

Ne putem antrena modelul TFT folosind familiarul Antrenor interfață de la PyTorch Lightning.

Observați următoarele lucruri:

  • Noi folosim Oprire devreme apel invers pentru a monitoriza pierderea de validare.
  • Noi folosim Placa de tensor pentru a înregistra valorile noastre de instruire și validare.
  • Modelul nostru folosește Pierdere cuantilă — un tip special de pierdere care ne ajută să emitem intervalele de predicție. Pentru mai multe despre funcția Quantile Loss, verificați acest articol.
  • Folosim 4 capetele de atenție, ca și hârtia originală.

Acum suntem pregătiți să construim și să ne instruim modelul:

Asta este! După 6 epoci, EarlyStopping începe și oprește antrenamentul.

Încărcați și salvați cel mai bun model

Nu uitați să vă salvați modelul. Deși îl putem mura, cea mai sigură opțiune este să salvăm cea mai bună epocă direct:

!zip -r model.zip lightning_logs/lightning_logs/version_1/*

Pentru a încărca din nou modelul, dezarhivați model.zip și executați următoarele - amintiți-vă doar cea mai bună cale de model:

Verificați Tensorboard

Aruncă o privire mai atentă la curbele de antrenament și validare cu Tensorboard:

Evaluarea modelului

Obțineți predicții asupra setului de validare și calculați media P50 (mediana cuantilă) de pe:

Ultimele 2 serii cronologice au pierderi ceva mai mari, deoarece magnitudinea lor relativă este, de asemenea, mare.

Trasează predicții privind datele de validare

Dacă trecem de mode=raw pe prezice() metoda, obținem mai multe informații, inclusiv predicții pentru toate cele șapte cuantile. Avem și acces la valorile atenției (mai multe despre asta mai târziu).

Aruncă o privire mai atentă la raw_predictions variabilă:

Noi folosim plot_prediction() pentru a ne crea parcelele. Desigur, ai putea să-ți faci propriul complot personalizat - the plot_prediction() are avantajul suplimentar de a adăuga valorile atenției.

Notă: Modelul nostru prezice următoarele 24 de puncte de date dintr-o dată. Acesta nu este un scenariu de prognoză continuu în care un model prezice a singur valoare de fiecare dată și „coase” toate predicțiile împreună.

Creăm câte o parcelă pentru fiecare consumator (5 în total).

Figura 3: Predicții privind datele de validare pentru MT_002
Figura 4: Predicții privind datele de validare pentru MT_004
Figura 5: Predicții privind datele de validare pentru MT_005
Figura 6: Predicții privind datele de validare pentru MT_006
Figura 7: Predicții privind datele de validare pentru MT_008

Rezultatele sunt destul de impresionante.

Our Transformator de fuziune temporală modelul a reușit să surprindă comportamentul tuturor celor 5 serii de timp, atât în ​​ceea ce privește sezonalitatea, cât și amploarea!

De asemenea, observați că:

  • Nu am efectuat nicio reglare hiperparametrică.
  • Nu am implementat nicio tehnică elegantă de inginerie a caracteristicilor.

Într-o secțiune ulterioară, arătăm cum să ne îmbunătățim modelul cu optimizarea hiperparametrului.

Plot Predicții pentru o anumită serie temporală

Anterior, am trasat predicții cu privire la datele de validare folosind idx argument, care iterează peste toate seriile temporale din setul nostru de date. Putem fi mai specifici și putem obține predicții pe o anumită serie de timp:

Figura 7: Previziune pentru ziua următoare MT_004 pe platoul de antrenament

In Figura 7, complotăm ziua înainte de MT_004 consumator pentru indice de timp=26512.

Amintiți-vă, coloana noastră de indexare a timpului hours_from_start începe de la 26304 și putem obține predicții de la 26388 încolo (pentru că am stabilit mai devreme min_encoder_length=max_encoder_length // 2 care este egal 26304 + 168//2=26388

Prognoze în afara eșantionului

Să creăm predicții în afara eșantionului, dincolo de punctul de date final al datelor de validare, adică 2014–09–07 23:00:00

Tot ce trebuie să facem este să creăm un nou cadru de date care să conțină:

  • Numărul de N=max_encoder_length datele trecute, care acționează ca fereastra de retrospectivă — the datele codificatorului în terminologia TFT.
  • Datele viitoare de dimensiune max_prediction_length pentru care dorim să ne calculăm previziunile — the date decodorului.

Putem crea predicții pentru toate cele 5 serii cronologice sau doar una. Figura 7 arată previziunile în afara eșantionului pentru consumator MT_002:

Figura 7: Predicția zilei înainte pentru MT_002

Previziunea exactă este un lucru, dar explicabilitatea contează foarte mult în zilele noastre.

Și este și mai rău pentru modelele Deep Learning, care sunt considerate cutii negre. Metode precum LĂMÂIE VERDE și SHAP poate oferi explicabilitate (într-o oarecare măsură), dar nu funcționează bine pentru seriile de timp. În plus, sunt metode externe post-hoc și nu sunt legate de un anumit model.

Transformator de fuziune temporală oferă trei tipuri de interpretabilitate:

  • Din punct de vedere sezonier: TFT își valorifică romanul Atenție interpretabilă cu mai multe capete mecanism pentru a calcula importanța pașilor de timp trecuti.
  • În funcție de caracteristici: TFT își folosește Rețea de selecție variabilă modul pentru a calcula importanța fiecărei caracteristici.
  • Robustețea evenimentelor extreme: Putem investiga cum se comportă seriile de timp în timpul evenimentelor rare

Dacă doriți să aflați în profunzime despre funcționarea interioară a Atenție interpretabilă cu mai multe capete și Rețea de selecție variabilă, verifica articolul meu anterior.

Interpretabilitate din punct de vedere al sezonului

TFT explorează ponderile atenției pentru a înțelege tiparele temporale în pașii de timp trecuti.

Liniile gri din toate graficele anterioare reprezintă scorurile de atenție. Uită-te din nou la acele comploturi - observi ceva? Figura 8 arată constatările de Figura 7 și, de asemenea, ține cont de scorurile de atenție:

Figura 8: Predicție pentru ziua următoare pentru MT_001, cu afișarea sezonalităților

Scorurile de atenție arată cât de impact sunt acei pași de timp în care modelul își emite predicția. Vârfurile mici reflectă sezonalitatea zilnică, în timp ce vârful mai înalt spre final implică probabil sezonalitatea săptămânală.

Dacă facem o medie a curbelor de atenție pentru toate etapele de timp și seriile de timp (nu doar cele 5 pe care le-am folosit în acest tutorial), vom obține forma cu aspect simetric în Figura 9 din hârtie TFT:

Figura 9: Setul de date Modele temporale pentru energie electrică (Sursă)

Întrebare: La ce bun asta? Nu putem estima pur și simplu modelele de sezonalitate cu metode precum diagramele ACF, descompunerea semnalului de timp etc.?

Răspuns: Adevărat. Cu toate acestea, studierea greutăților atenției TFT are avantaje suplimentare:

  1. Putem confirma că modelul nostru surprinde dinamica sezonieră aparentă a secvențelor noastre.
  2. Modelul nostru poate dezvălui, de asemenea, modele ascunse, deoarece ponderile atenției ferestrelor de intrare curente iau în considerare toate intrările anterioare.
  3. Graficul ponderilor atenției nu este același cu un grafic al autocorelației: graficul autocorelației se referă la o anumită secvență, în timp ce ponderile atenției aici se concentrează pe impactul fiecărui pas de timp, analizând toate covariatele și seriile de timp.

Interpretabilitate în funcție de caracteristici

Rețea de selecție variabilă componenta TFT poate estima cu ușurință importanțele caracteristicilor:

Figura 10: Oferă importanță pentru datele de validare

In Figura 10, observăm următoarele:

  • hour și day_of_week au scoruri puternice, atât ca observații anterioare, cât și ca covariabile viitoare. Criteriul de referință din lucrarea originală împărtășește aceeași concluzie.
  • power_usage este, evident, cea mai impactantă covariabilă observată.
  • consumer_id nu este foarte semnificativ aici deoarece folosim doar 5 consumatori. În lucrarea TFT, în care autorii folosesc toți cei 370 de consumatori, această variabilă este mai semnificativă.

Notă: Dacă variabila statică de grupare nu este importantă, este foarte probabil că setul de date poate fi modelat la fel de bine printr-un singur model de distribuție (cum ar fi ARIMA).

Detectarea evenimentelor extreme

Seriile temporale sunt renumite pentru că sunt susceptibile la schimbări bruște ale proprietăților lor în timpul evenimentelor rare (numite și ca șocuri).

Și mai rău, acele evenimente sunt foarte evazive. Imaginați-vă dacă variabila țintă devine volatilă pentru o perioadă scurtă, deoarece o covariabilă schimbă în tăcere comportamentul:

Este un zgomot aleatoriu sau un model persistent ascuns care scapă de modelul nostru?

Cu TFT, putem analiza robustețea fiecărei caracteristici individuale în intervalul lor de valori. Din păcate, setul de date actual nu prezintă volatilitate sau evenimente rare - acestea sunt mai probabil să fie găsite în datele financiare, de vânzări și așa mai departe. Totuși, vom arăta cum să le calculăm:

Unele caracteristici nu au toate valorile lor prezente în setul de date de validare, așa că arătăm doar hour și consumer_id:

Figura 11: Previziuni vs valori reale (medii normalizate) pe oră
Figura 12: Predicții vs valori reale (medii normalizate) pe consumer_id

În ambele cifre, rezultatele sunt încurajatoare. În Figura 12, observăm acel consumator MT_004 ușor subperformanțe în comparație cu alți consumatori. Am putea verifica acest lucru dacă normalizăm pierderea P50 a fiecărui consumator cu consumul mediu de energie pe care am calculat-o anterior.

Barele gri indică distribuția fiecărei variabile. Un lucru pe care îl fac întotdeauna este să găsesc ce valori au o frecvență scăzută. Apoi, verific cum funcționează modelul în acele zone. Prin urmare, puteți detecta cu ușurință dacă modelul dvs. surprinde comportamentul evenimentelor rare.

În general, puteți utiliza această caracteristică TFT pentru a verifica modelul dvs. pentru punctele slabe și pentru a trece la investigații suplimentare.

Putem folosi fără probleme Transformator de fuziune temporală cu Optuna pentru a efectua reglarea hiperparametrului:

Problema este că, deoarece TFT este un model bazat pe Transformer, veți avea nevoie de resurse hardware semnificative!

Transformator de fuziune temporală este, fără îndoială, o piatră de hotar pentru comunitatea Time-Series.

Nu numai că modelul obține rezultate SOTA, dar oferă și un cadru pentru interpretabilitatea predicțiilor. Modelul este disponibil și în Darts biblioteca python, care se bazează pe biblioteca PyTorch Forecasting.

În cele din urmă, dacă sunteți curios să aflați despre arhitectura Transformator de fuziune temporală în detaliu, verificați articol însoțitor pe hârtia originală.

Transformator de fuziune temporală: Prognoza serii temporale cu învățare profundă — Tutorial complet republicat din sursă https://towardsdatascience.com/temporal-fusion-transformer-time-series-forecasting-with-deep-learning-complete-tutorial-d32c1e51cd91?source= rss—-7f60cf5620c9—4 prin https://towardsdatascience.com/feed

<!–

->

Timestamp-ul:

Mai mult de la Consultanți Blockchain