Temporal Fusion Transformer: tidsserieprognoser med djupinlärning — komplett handledning

Skapa korrekta och tolkningsbara förutsägelser

Skapad med DALLE [1]

Enligt [2], Temporal Fusion Transformator överträffar alla framstående Deep Learning-modeller för tidsserieprognoser.

Inklusive en utvald Gradient Boosting Tree modell för tabellformade tidsseriedata.

Men vad är det? Temporal Fusion Transformer (TFT)[3] och varför är det så intressant?

I den här artikeln förklarar vi kortfattat nyheterna i Temporal Fusion Transformator och bygga ett projekt från slut till slut på Energiefterfrågan prognoser. Specifikt kommer vi att täcka:

  • Hur man förbereder vår data för TFT-formatet.
  • Hur man bygger, tränar och utvärderar TFT-modellen.
  • Hur man får förutsägelser om valideringsdata och förutsägelser utanför urvalet.
  • Hur man beräknar egenskapens betydelse, säsongsmönster, och extrema händelser robusthet med hjälp av den inbyggda modellen tolkbar uppmärksamhet mekanism.

Låt oss dyka in!

För en djupgående analys av Temporal Fusion Transformer-arkitekturen, kolla mitt tidigare Artikeln.

Temporalisk Fanvändning Transifierare (TFT) är en transformatorbaserad modell som utnyttjar självuppmärksamhet för att fånga den komplexa tidsmässiga dynamiken i flera tidssekvenser.

TFT stöder:

  • Flera tidsserier: Vi kan träna en TFT-modell på tusentals univariata eller multivariata tidsserier.
  • Multi-Horizon Prognos: Modellen matar ut flerstegsförutsägelser av en eller flera målvariabler – inklusive förutsägelseintervall.
  • Heterogena egenskaper: TFT stöder många typer av funktioner, inklusive tidsvarianter och statiska exogena variabler.
  • Tolkbara förutsägelser: Förutsägelser kan tolkas i termer av varierande betydelse och säsongsvariationer.

En av dessa egenskaper är unik för Temporal Fusion Transformator. Vi kommer att ta upp detta i nästa avsnitt.

Bland anmärkningsvärda DL-tidsseriemodeller (t.ex. DeepAR[4]), TFT sticker ut eftersom den stöder olika typer av funktioner. Dessa är:

  • Tidsvarierande känd
  • Tidsvarierande okänd
  • Tidsinvariant verklig
  • Tidsinvariant kategorisk

Föreställ dig till exempel att vi har en försäljningsprognos fall:

Låt oss säga att vi måste förutsäga försäljningen av 3 produkter. De num sales är målvariabeln. De CPI index eller number of visitors är tidsvarierande okänd funktioner eftersom de bara är kända fram till prediktionstiden. Dock, holidaysoch special days är tidsvarierande kända evenemang.

Smakämnen product id is en tidsinvariant (statisk) kategori funktion. Andra funktioner som är numeriska och inte tidsberoende som t.ex yearly_revenue kan kategoriseras som tidsinvariant verklig.

Innan vi går vidare till vårt projekt kommer vi först att visa en minihandledning om hur du konverterar din data till utökat tidsserieformat.

Notera: Alla bilder och figurer i denna artikel är skapade av författaren.

För den här handledningen använder vi TemporalFusionTransformer modell från PyTorch-prognoser bibliotek och PyTorch Lightning:

pip installera ficklampa pytorch-lightning pytorch_forecasting

Hela processen innefattar 3 saker:

  1. Skapa en pandas dataram med vår tidsseriedata.
  2. Slå in vår dataram i en TimeSeriesDataset exempel.
  3. Passera vår TimeSeriesDataset instans till TemporalFusionTransformer.

Smakämnen TimeSeriesDataset är mycket användbart eftersom det hjälper oss att specificera om funktioner är tidsvarierande eller statiska. Dessutom är det det enda formatet som TemporalFusionTransformer accepterar.

Låt oss skapa en minimal träningsdatauppsättning för att visa hur TimeSeriesDataset verk:

Vi bör formatera våra data på följande sätt: Varje färgad ruta representerar en annan tidsserie, representerad av dess group värde.

Figur 1: Dataramen sample_data pandas

Den viktigaste kolumnen i vår dataram är time_idx — den bestämmer provsekvensen. Om det inte saknas observationer bör värdena öka med +1 för varje tidsserie.

Därefter slår vi in ​​vår dataram i en TimeSeriesDataset exempel:

Alla argument är självförklarande: The max_encoder_length definierar tillbakablicksperioden och max_prediction_length anger hur många datapunkter som kommer att förutsägas. I vårt fall ser vi tillbaka 3 tidssteg i det förflutna för att producera 2 förutsägelser.

Smakämnen TimeSeriesDataset instans fungerar nu som en dataladdare. Låt oss skriva ut en batch och kontrollera hur vår data kommer att skickas till TFT:

Denna batch innehåller träningsvärdena [0,1] från den första tidsserien (group 0) och testvärdena[2,3,4]. Om du kör den här koden igen får du andra värden eftersom data blandas som standard.

Vårt projekt kommer att använda Elbelastningsdiagram20112014 [5] dataset från UCI. Anteckningsboken för detta exempel kan laddas ner från här.:

Denna datauppsättning innehåller strömförbrukningen (i kW) för 370 klienter/konsumenter med en 15-minutersfrekvens. Uppgifterna sträcker sig över 4 år (2011–2014).

Vissa konsumenter skapades efter 2011, så deras strömförbrukning är initialt noll.

Vi gör dataförbehandling enl [3]:

  • Aggregera vår målvariabel power_usage per timme.
  • Hitta det tidigaste datumet för varje tidsserie där effekten inte är noll.
  • Skapa nya funktioner: month, day, hour och day_of_week.
  • Välj alla dagar mellan 2014–01–01 och 2014–09–07.

Låt oss börja:

Hämta data

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

Förbehandling av data

Varje kolumn representerar en konsument. Mest initiala power_usage värdena är 0.

Därefter aggregerar vi till timdata. På grund av modellens storlek och komplexitet tränar vi vår modell på endast 5 konsumenter (för de med värden som inte är noll).

Nu förbereder vi vår datauppsättning för TimeSeriesDataset formatera. Observera att varje kolumn representerar olika tidsserier. Därför "smälter" vi vår dataram, så att alla tidsserier staplas vertikalt istället för horisontellt. I processen skapar vi våra nya funktioner.

Den slutliga förbehandlade dataramen anropas time_df. Låt oss skriva ut innehållet:

Smakämnen time_df är nu i rätt format för TimeSeriesDataset. Som du har gissat vid det här laget, eftersom granulariteten är varje timme hours_from_start variabel kommer att vara tidsindex.

Utforskande dataanalys

Valet av 5 konsumenter/tidsserier är inte slumpmässigt. De power usage av varje tidsserie har olika egenskaper, såsom medelvärdet:

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

Låt oss plotta den första månaden i varje tidsserie:

Figur 2: Den första månaden av alla 5 tidsserier/konsumenter.

Det finns ingen märkbar trend, men varje tidsserie har lite olika säsongsvariationer och amplitud. Vi kan ytterligare experimentera och kontrollera stationaritet, signalnedbrytningar och så vidare, men i vårt fall fokuserar vi bara på modellbyggande aspekten.

Lägg också märke till att andra tidsserieprognosmetoder som ARIMA måste uppfylla några krav (till exempel måste tidsserien först bli stationär.) Med TFT kan vi lämna våra data som de är.

Skapa DataLoaders

I detta steg passerar vi vår time_df till TimeSeriesDataSet format som är oerhört användbart eftersom:

  • Det besparar oss från att skriva vår egen Dataloader.
  • Vi kan specificera hur TFT kommer att hantera datauppsättningens funktioner.
  • Vi kan enkelt normalisera vår datauppsättning. I vårt fall är normalisering obligatorisk eftersom alla tidssekvenser skiljer sig åt i storlek. Därför använder vi GroupNormalizer för att normalisera varje tidsserie individuellt.

Vår modell använder en tillbakablicksperiod på en vecka (7*24) för att förutsäga strömförbrukningen för de kommande 24 timmarna.

Observera också att hours_from_start är både tidsindex och en tidsvarierande funktion. De power_usage är vår målvariabel. För demonstrationens skull är vårt valideringsset sista dagen:

Baslinjemodell

Därefter steget som nästan alla glömmer: En grundmodell. Speciellt i tidsserieprognoser kommer du att bli förvånad över hur ofta en naiv prediktor överträffar ens en finare modell!

Som en naiv baslinje förutsäger vi strömförbrukningskurvan för föregående dag:

Utbildning av Temporal Fusion Transformer Model

Vi kan träna vår TFT-modell med hjälp av det välbekanta Tränare gränssnitt från PyTorch Lightning.

Lägg märke till följande saker:

  • Vi använder Tidig stopp återuppringning för att övervaka valideringsförlusten.
  • Vi använder Spännbräda för att logga våra utbildnings- och valideringsmått.
  • Vår modell använder Kvantilförlust — en speciell typ av förlust som hjälper oss att mata ut prediktionsintervallen. För mer om funktionen Quantile Loss, kolla in den här artikeln.
  • Vi använder 4 uppmärksamhet huvuden, som originalpapperet.

Vi är nu redo att bygga och träna vår modell:

Det är allt! Efter 6 epoker slår EarlyStopping in och avbryter träningen.

Ladda och spara den bästa modellen

Glöm inte att spara din modell. Även om vi kan sylta den, är det säkraste alternativet att spara den bästa epoken direkt:

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

För att ladda modellen igen, packa upp model.zip och kör följande — kom bara ihåg den bästa modellvägen:

Kontrollera Tensorboard

Ta en närmare titt på tränings- och valideringskurvor med Tensorboard:

Modellutvärdering

Få förutsägelser om valideringsuppsättningen och beräkna medelvärdet P50 (kvantil median) förlust:

De två senaste tidsserierna har lite högre förlust eftersom deras relativa storlek också är hög.

Rita förutsägelser om valideringsdata

Om vi ​​passerar mode=raw förutspå() metoden får vi mer information, inklusive förutsägelser för alla sju kvantiler. Vi har även tillgång till uppmärksamhetsvärdena (mer om det senare).

Ta en närmare titt på raw_predictions variabel:

Vi använder plot_prediction() att skapa våra tomter. Naturligtvis kan du göra din egen skräddarsydda tomt - den plot_prediction() har den extra fördelen att lägga till uppmärksamhetsvärdena.

Notera: Vår modell förutsäger de kommande 24 datapunkterna på en gång. Detta är inte ett rullande prognosscenario där en modell förutsäger en enda värde varje gång och "häftar" ihop alla förutsägelser.

Vi skapar en tomt för varje konsument (5 totalt).

Figur 3: Förutsägelser om valideringsdata för MT_002
Figur 4: Förutsägelser om valideringsdata för MT_004
Figur 5: Förutsägelser om valideringsdata för MT_005
Figur 6: Förutsägelser om valideringsdata för MT_006
Figur 7: Förutsägelser om valideringsdata för MT_008

Resultaten är ganska imponerande.

Vår Temporal Fusion Transformator Modellen kunde fånga beteendet för alla 5 tidsserierna, både vad gäller säsong och storlek!

Observera också att:

  • Vi utförde ingen hyperparameterjustering.
  • Vi har inte implementerat någon fancy funktionsteknik.

I ett efterföljande avsnitt visar vi hur vi kan förbättra vår modell med hyperparameteroptimering.

Plotta förutsägelser för en specifik tidsserie

Tidigare plottade vi förutsägelser om valideringsdata med hjälp av idx argument, som itererar över alla tidsserier i vår datauppsättning. Vi kan vara mer specifika och producera förutsägelser om en specifik tidsserie:

Figur 7: Förutsägelse för dagen framåt MT_004 på träningssetet

In Figur 7, vi planerar dagen före MT_004 konsument för tidsindex=26512.

Kom ihåg vår tidsindexeringskolumn hours_from_start börjar från 26304 och vi kan få förutsägelser från 26388 och framåt (eftersom vi ställt in tidigare min_encoder_length=max_encoder_length // 2 vilket är lika med 26304 + 168//2=26388

Prognoser utanför urvalet

Låt oss skapa förutsägelser utanför urvalet, bortom den slutliga datapunkten för valideringsdata – dvs 2014–09–07 23:00:00

Allt vi behöver göra är att skapa en ny dataram som innehåller:

  • Antalet N=max_encoder_length tidigare datum, som fungerar som tillbakablicksfönstret - den kodardata i TFT-terminologi.
  • Framtida datum för storlek max_prediction_length för vilka vi vill beräkna våra förutsägelser - den avkodardata.

Vi kan skapa förutsägelser för alla fem av våra tidsserier, eller bara en. Figur 7 visar prognoserna utanför urvalet för konsumenten MT_002:

Figur 7: Prognos för dagen framåt för MT_002

Exakta prognoser är en sak, men förklaringsförmåga spelar också stor roll nuförtiden.

Och det är ännu värre för Deep Learning-modeller, som anses vara svarta lådor. Metoder som t.ex KALK och SHAP kan ge förklarabarhet (till viss del) men fungerar inte bra för tidsserier. Dessutom är de externa post-hoc-metoder och är inte bundna till en viss modell.

Temporal Fusion Transformator ger tre typer av tolkningsmöjligheter:

  • Säsongsmässigt: TFT utnyttjar sin roman Tolkbar Multi-Head Attention mekanism för att beräkna betydelsen av tidigare tidssteg.
  • Funktionsmässigt: TFT utnyttjar sin Variabelt urvalsnätverk modul för att beräkna vikten av varje funktion.
  • Robusthet vid extrema händelser: Vi kan undersöka hur tidsserier beter sig under sällsynta händelser

Om du vill lära dig på djupet om det inre av Tolkbar Multi-Head Attention och Variabelt urvalsnätverk, kolla min tidigare artikel.

Säsongsmässigt tolkbarhet

TFT utforskar uppmärksamhetsvikterna för att förstå de tidsmässiga mönstren över tidigare tidssteg.

De grå linjerna i alla tidigare plot representerar uppmärksamhetspoängen. Titta på de där tomterna igen — märker du något? Figur 8 visar resultaten av Figur 7 och står också för uppmärksamhetspoängen:

Figur 8: Dagsförutsägelse för MT_001 med säsongsvariationer som visas

Uppmärksamhetspoängen avslöjar hur effektfulla de tidssteg är när modellen ger ut sin förutsägelse. De små topparna återspeglar den dagliga säsongsvariationen, medan den högre toppen mot slutet antagligen innebär den veckovisa säsongsvariationen.

Om vi ​​snittar uppmärksamhetskurvorna över alla tidssteg och tidsserier (inte bara de 5 vi använde i denna handledning), kommer vi att få den symmetriskt utseende formen i Figur 9 från TFT-pappret:

Figur 9: Temporal Patterns for Electricity dataset (Källa)

Fråga: Vad hjälper det här? Kan vi inte helt enkelt uppskatta säsongsmönster med metoder som ACF-plottar, tidssignalsupplösning etc.?

Svar: Sann. Att studera uppmärksamhetsvikterna för TFT har dock extra fördelar:

  1. Vi kan bekräfta att vår modell fångar den uppenbara säsongsbetonade dynamiken i våra sekvenser.
  2. Vår modell kan också avslöja dolda mönster eftersom uppmärksamhetsvikterna för de nuvarande inmatningsfönstren tar hänsyn till alla tidigare ingångar.
  3. Uppmärksamhetsviktsdiagrammet är inte detsamma som ett autokorrelationsdiagram: Autokorrelationsdiagrammet hänvisar till en viss sekvens, medan uppmärksamhetsvikterna här fokuserar på effekten av varje tidssteg genom att titta över alla kovariater och tidsserier.

Funktionsmässig tolkning

Smakämnen Variabelt urvalsnätverk komponent av TFT kan enkelt uppskatta funktioner viktiga:

Figur 10: Har betydelse för valideringsdata

In Figur 10, märker vi följande:

  • Smakämnen hour och day_of_week har starka poäng, både som tidigare observationer och framtida kovariater. Riktmärket i originaldokumentet delar samma slutsats.
  • Smakämnen power_usage är uppenbarligen den mest påverkande observerade kovariaten.
  • Smakämnen consumer_id är inte särskilt betydande här eftersom vi bara använder 5 konsumenter. I TFT-tidningen, där författarna använder alla 370 konsumenter, är denna variabel mer signifikant.

Notera: Om din gruppering av statiska variabel inte är viktig, är det mycket troligt att din datauppsättning också kan modelleras lika bra av en enda distributionsmodell (som ARIMA).

Detektion av extrema händelser

Tidsserier är ökända för att vara mottagliga för plötsliga förändringar i deras egenskaper under sällsynta händelser (även kallad chocker).

Ännu värre, dessa händelser är mycket svårfångade. Föreställ dig om din målvariabel blir volatil under en kort period eftersom en kovariat tyst ändrar beteende:

Är detta något slumpmässigt brus eller ett dolt ihållande mönster som undkommer vår modell?

Med TFT kan vi analysera robustheten hos varje enskild funktion över deras värdeintervall. Tyvärr uppvisar den aktuella datamängden inte volatilitet eller sällsynta händelser - det är mer sannolikt att de återfinns i finansiella data, försäljningsdata och så vidare. Ändå kommer vi att visa hur man beräknar dem:

Vissa funktioner har inte alla sina värden närvarande i valideringsdataset, så vi visar bara hour och consumer_id:

Figur 11: Förutsägelser vs faktiska värden (normaliserade medelvärden) på timme
Figur 12: Förutsägelser vs faktiska värden (normaliserade medelvärden) på konsument_id

I båda figurerna är resultaten uppmuntrande. I Figur 12, märker vi att konsumenten MT_004 underpresterar något jämfört med andra konsumenter. Vi skulle kunna verifiera detta om vi normaliserar P50-förlusten för varje konsument med deras genomsnittliga strömförbrukning som vi beräknade tidigare.

De grå staplarna anger fördelningen av varje variabel. En sak jag alltid gör är att hitta vilka värden som har en låg frekvens. Sedan kollar jag hur modellen presterar i dessa områden. Därför kan du enkelt upptäcka om din modell fångar beteendet av sällsynta händelser.

I allmänhet kan du använda den här TFT-funktionen för att undersöka din modell för svagheter och gå vidare till ytterligare undersökning.

Vi kan sömlöst använda Temporal Fusion Transformator med Välja för att utföra hyperparameterjustering:

Problemet är att eftersom TFT är en transformatorbaserad modell kommer du att behöva betydande hårdvaruresurser!

Temporal Fusion Transformator är utan tvekan en milstolpe för Time-Series-communityt.

Modellen uppnår inte bara SOTA-resultat utan ger också ett ramverk för tolkningsbarheten av förutsägelser. Modellen finns även i Dart python-bibliotek, som är baserat på PyTorch Forecasting-biblioteket.

Slutligen, om du är nyfiken på att lära dig mer om arkitekturen Temporal Fusion Transformator i detalj, kontrollera medföljande artikel på originalpapperet.

Temporal Fusion Transformer: Time Series Forecasting with Deep Learning — Komplett handledning publicerad på nytt från källan https://towardsdatascience.com/temporal-fusion-transformer-time-series-forecasting-with-deep-learning-complete-tutorial-d32c1e51cd91?source= rss—-7f60cf5620c9—4 via https://towardsdatascience.com/feed

<!–

->

Tidsstämpel:

Mer från Blockchain-konsulter