(Acest articol a fost publicat pentru prima dată pe R funcționeazăși a contribuit cu drag la R-Bloggers). (Puteți raporta problema despre conținutul de pe această pagină aici)
Doriți să vă împărtășiți conținutul pe R-Bloggers? Faceți clic aici dacă aveți un blog sau aici dacă nu.
Această postare este o primă privire asupra lui Nixtla TimeGPT
Transformator generativ, pre-instruit pentru previziuni ale seriilor de timp folosind nixtlar
Pachet R.
Așa cum este descris în Garza și colab. (2021), TimeGPT este un model de serie de timp bazat pe transformatoare cu mecanisme de auto-atenție. Arhitectura cuprinde o structură de decodificator cu mai multe straturi, fiecare cu conexiuni reziduale și normalizare a straturilor. Codificatorul, o grămadă de straturi de auto-atenție cu mai multe capete, urmată de o rețea neuronală de avans, procesează seria de timp de intrare. Decodorul, care este similar cu codificatorul, generează prognoza. Decodorul include un strat suplimentar de atenție cu mai multe capete care ia ieșirea codificatorului ca intrare. Modelul este instruit folosind o strategie de alimentare a profesorilor, unde decodificatorul primește valorile adevărului la sol în timpul antrenamentului. Modelul este apoi utilizat pentru prognoză prin hrănirea predicțiilor modelului înapoi ca intrare în timpul inferenței.
Site -ul NIXTLA oferă o cantitate considerabilă de materiale explicative, documentație și exemple de cod în Python. nixtlar
Pachetul înfășoară codul Python pentru a furniza o interfață R. Documentația pachetului pentru versiunea 0.6.2 nu este pe deplin funcțiile R, dar vinietele oferă exemple de cod suficiente pentru a începe.
Înainte de a începe cu TimeGPT, va trebui să vă înregistrați pentru o cheie API. Procesul este destul de ușor și este descris în această vinie.
Afișați codul
library(tidyverse) library(forecast) library(prophet) library(nixtlar)
Datele
Setul de date privind energia electrică inclus în nixtlar
Pachetul conține observații pe oră ale consumului de energie electrică generată provenită de la PJM Interconection LLC, o organizație regională de transmisie care face parte din rețeaua de interconectare estică din Statele Unite. Există cinci serii de timp diferite, cu date luate din 2012 până în 2018.
Rețineți că datele de energie electrică sunt în format „lung” și că ds
Variabila de timp este datele personajelor.
Afișați codul
df <- nixtlar::electricity glimpse(df)
Rows: 8,400 Columns: 3 $ unique_id"BE", "BE", "BE", "BE", "BE", "BE", "BE", "BE", "BE", "BE", … $ ds "2016-10-22 00:00:00", "2016-10-22 01:00:00", "2016-10-22 02… $ y 70.00, 37.10, 37.10, 44.75, 37.10, 35.61, 34.55, 50.49, 61.5…
O privire la cadrul de date „larg” arată că diversele serii nu acoperă aceleași perioade de timp.
Afișați codul
df_wide <- df |> pivot_wider(names_from = unique_id, values_from = y) head(df_wide)
# A tibble: 6 × 6 ds BE DE FR NP PJM1 2016-10-22 00:00:00 70 NA 54.7 NA NA 2 2016-10-22 01:00:00 37.1 NA 51.2 NA NA 3 2016-10-22 02:00:00 37.1 NA 48.9 NA NA 4 2016-10-22 03:00:00 44.8 NA 45.9 NA NA 5 2016-10-22 04:00:00 37.1 NA 41.2 NA NA 6 2016-10-22 05:00:00 35.6 NA 41.4 NA NA
Parcele indică faptul că toate seriile prezintă perioade de volatilitate considerabilă. Seria Be, DE și FR pare a fi staționară. NP tendințe în sus, iar seria PJM pare a fi neliniară.
Afișați codul
df2 <- df |> mutate(time = as.POSIXct(ds, format = "%Y-%m-%d %H:%M:%S")) |> group_by(unique_id) p <- df2 |> ggplot(aes(x = time, y = y, color = unique_id)) + geom_line() + facet_wrap( ~ unique_id, scales = "free") p
Furne de timp
Voi începe prin a arăta nixtlar
Funcția de prognoză, care poate gestiona mai multe serii de timp, prognozând cu opt ore înainte folosind toate datele. Parametrul h
specifică numărul de pași înainte de prognoză și level
Specifică nivelul de încredere pentru prognoză.
Aici este încorporat nixtlar
Funcția de complot.
Afișați codul
#nixtla_client_plot(df, nixtla_client_fcst, max_insample_length = 200)
Acest complot folosește ggplot2
să se concentreze asupra prognozelor de 8 puncte folosind toate datele. Parametrul de nivel indică faptul că trebuie calculate atât intervale de încredere de 80%, cât și 96%.
Afișați codul
# nixtla_client_fcst <- nixtla_client_forecast(df, h = 8, level = c(80,95)) # saveRDS(nixtla_client_fcst, "nixtla_client_fcst.rds") nixtla_client_fcst <- readRDS("nixtla_client_fcst.rds") ncf_df <- nixtla_client_fcst |> mutate(time = as.POSIXct(ds, format = "%Y-%m-%d %H:%M:%S")) |> group_by(unique_id) names(ncf_df) <- c("unique_id", "ds", "TimeGPT", "lon", "loe", "hie", "hin") pf <- ncf_df |> ggplot(aes(x = ds, y = TimeGPT, color = unique_id)) + geom_line() + geom_ribbon(aes(ymin = lon, ymax = hin), linetype = 2, alpha = 0.1) + facet_wrap( ~ unique_id, scales = "free") pf
Pentru restul acestei postări, voi lucra doar cu datele Be și voi face câteva testări simple înapoi. Voi împărți datele într -un set de instruire și un set de teste care conține 24 de ore în valoare de observații. Apoi, mă voi potrivi cu modelele de prognoză a seriilor de timp și voi compara cât de bine se descurcă față de datele reale și unul cu celălalt. Rețineți, nu voi încerca nicio reglare a acestor modele, în încercarea de a face o comparație corectă, „în afara casei”.
Afișați codul
NF <- 24 BE_df_wide <- df |> pivot_wider(names_from = unique_id, values_from = y) |> select(ds, BE) |> drop_na() BE_train_df <- BE_df_wide %>% filter(row_number() <= n() - NF) BE_test_df <- tail(BE_df_wide, NF) BE_train_df <- BE_train_df |> rename(y = BE) |> mutate(unique_id = "BE") BE_test_df <- BE_test_df |> rename(y = BE)
nixtla_client_forecast()
Funcția este principala nixtlar
Funcție de prognoză. (Am rulat deja această funcție și am salvat fișierul RDS Rezultate pentru a nu efectua un apel API de fiecare dată când codul este rulat în timpul procesului de construire a blogului.)
Afișați codul
#nixtla_fcst <- nixtla_client_forecast(BE_train_df, h = NF, level = 95) #saveRDS(nixtla_fcst, "nixtla_fcst_24.rds") nixtla_fcst <- readRDS("nixtla_fcst_24.rds") names(nixtla_fcst) <- c("unique_id", "ds", "TimeGPT", "lo95", "up95")
Aici, creez un cadru de date pentru a deține valorile reale și prognozate.
Afișați codul
fcst_df <- tail(nixtla_fcst, NF) |> select(ds, TimeGPT) |> rename(time = ds, tgpt_fcst = TimeGPT) |> mutate(elec_actual = BE_test_df$y) head(fcst_df)
time tgpt_fcst elec_actual 1 2016-12-30 00:00:00 38.82010 44.30 2 2016-12-30 01:00:00 36.29234 44.30 3 2016-12-30 02:00:00 34.97838 41.26 4 2016-12-30 03:00:00 32.99565 40.62 5 2016-12-30 04:00:00 31.58322 40.07 6 2016-12-30 05:00:00 33.27422 41.02
Unele prognoze comparative
Această secțiune următoare a codului pune datele de instruire într -un format de serie de timp care este potrivit pentru forecast::auto.arima()
şi forecast::auto.ets()
Funcții. Ambele funcții necesită ca datele să fie exprimate ca un ts()
obiect. Versiunea originală a acestei postări a formatat datele ca xts()
Obiect: O eroare care a afectat substanțial ARIMA și previziunile de netezire exponențiale. Există o problemă cu utilizarea ts()
: datele de energie electrică au aspecte multisasonale care ts()
nu a fost conceput pentru a se acomoda. Codul de mai jos care creează ts()
Obiectul tratează timpul ca un indice de zile cu o perioadă de 24 și ignoră toate restul informațiilor de sezon din setul de date. În mod clar, aceasta nu este o soluție perfectă, dar oferă o soluție de soluție suficient de bună pentru scopul meu de a compara TimeGPT
cu câteva prognoze automate foarte simple. Veți vedea mai jos că prognoza ARIMA este destul de bună.
Afișați codul
auto_train <- BE_train_df |> select(-unique_id) |> mutate(time = 1:length(ds))|> select(-ds) elec_ts <- ts(auto_train$y, frequency = 24)
Prognoza Arima cu auto.arima()
auto.arima()
Funcție din forecast
Pachetul se potrivește cu un model destul de sofisticat ARIMA (2,1,1) (1,0,1) (24). Parametrii dintre paranteze înseamnă doi termeni autoregresivi, o diferență, un termen mediu în mișcare, un termen autoregresiv sezonier, fără diferențiere sezonieră și un termen mediu în mișcare sezonier. (24) indică faptul că modelul sezonier se repetă la fiecare 24 de observații. (Rețineți că, deoarece prognoza ARIMA durează câteva secunde pentru a rula, citesc formularul unui fișier RDS pentru a accelera procesul blogului.)
Afișați codul
#Run the following three lines to actually generate the forecast on your own. # arima_fcst <- elec_ts |> # auto.arima() |> # forecast(h = NF , level = 95) #saveRDS(arima_fcst, "arima_fcst_24.rds") arima_fcst <- readRDS("arima_fcst_24.rds")
Prognoză exponențială de netezire cu ets()
Pentru că nu am oferit nicio îndrumare, ets()
Funcție din forecast
Pachetul se potrivește unui model ETS (M, N, M). Acesta este un model multiplicativ fără o componentă de tendință, în care atât eroarea, cât și componentele sezoniere sunt multiplicative. Primul M indică faptul că termenul de eroare (fluctuație aleatorie) este modelat ca o componentă multiplicativă în care efectul termenului de eroare asupra valorii prognozate este proporțional cu nivelul seriei de timp.
Afișați codul
ets_fcst <- elec_ts |> ets() |> # number of periods to forecast forecast(h = NF)
Profetul Profet
Îl întreb și pe prophet()
Funcție din prophet
Pachet pentru o potrivire automată folosind parametrii impliciti. Printre altele, acest lucru înseamnă o curbă de creștere liniară, cu sezonalitate aditivă și estimări automate pentru sezonalitatea zilnică. Cât despre TimeGPT
prognoză, modelul este potrivit folosindBE_train_df
Cadru de date în care variabila de timp este datele personajelor. make_future_dataframe()
funcția creează un cadru de date cu aceeași structură ca BE_train_df
Dar cu ds
coloană extinsă de NF
perioade.
Afișați codul
prophet_fit <- prophet(BE_train_df) future <- make_future_dataframe( prophet_fit, periods = NF, freq = 3600, include_history = FALSE ) prophet_fcst <- predict(prophet_fit, future)
Rezultate și discuții
Înainte de a complota, să aruncăm o privire asupra cadrului de date larg care deține prognozele.
Afișați codul
fcst_df2 <- fcst_df |> mutate( arima_fcst = as.vector(arima_fcst$mean), ets_fcst = as.vector(ets_fcst$mean), prophet_fcst = prophet_fcst$yhat ) head(fcst_df2)
time tgpt_fcst elec_actual arima_fcst ets_fcst prophet_fcst 1 2016-12-30 00:00:00 38.82010 44.30 46.19057 37.72396 32.05748 2 2016-12-30 01:00:00 36.29234 44.30 44.99377 34.97583 29.74375 3 2016-12-30 02:00:00 34.97838 41.26 44.06233 32.89185 22.66588 4 2016-12-30 03:00:00 32.99565 40.62 42.45347 29.87591 15.85864 5 2016-12-30 04:00:00 31.58322 40.07 43.05403 27.56602 15.62841 6 2016-12-30 05:00:00 33.27422 41.02 44.28001 29.15387 23.54824
Apoi, modelați datele în format lung și complot.
Afișați codul
fcst_dft2_long <- fcst_df2 %>% pivot_longer(!time, names_to = "method", values_to = "mean") q <- fcst_dft2_long |> ggplot(aes( x = time, y = mean, group = method, color = method )) + geom_line() + geom_point() + ggtitle("TimeGPT vs ARIMA vs ETS vs Prophet vs actual data - 24 Point Forecast") q
Prognoza TimeGPT arată destul de bine. Nu cred că aceasta este o mare surpriză, având în vedere că oamenii din Nixtla au ales setul de date de energie electrică pentru a -și arăta transformatorul. Cu toate acestea, este curios, că, cu excepția unui punct, prognoza TimeGPT este mai mică decât datele reale. De asemenea, este interesant faptul că unele dintre punctele prognozate care sunt mai departe sunt o potrivire mai bună cu datele reale decât punctele inițiale de prognoză.
Prognoza ARIMA este foarte bună. Urmărește foarte îndeaproape primele câteva puncte, subliniază vârfurile datelor reale, dar se recuperează după ambele vârfuri și urmărește datele bine spre sfârșitul perioadei de prognoză.
Prognoza exponențială de netezire rămâne în mare parte mult sub datele reale, dar și doza destul de bine în general.
Modelul Prophet Black Box se desfășoară la tendințele descendente la începutul și sfârșitul perioadei de prognoză. Presupunerea mea este că, cu un mic profet de reglare ar putea face mult mai bine.
De asemenea, este demn de remarcat faptul că alegerea cel mai bun Prognoza depinde și de obiectivele tale. De exemplu, în anumite circumstanțe, s -ar putea prefera o prognoză care să reproducă tiparele sezoniere sau o posibilă volatilitate, mai degrabă decât o precizie generală. Pentru acest exercițiu, vedem că TimeGPT imită volatilitatea datelor reale, dar că prognoza ARIMA are cea mai mică eroare medie pătrată. Rețineți, de asemenea, că ARIMA și previziunile de netezire exponențiale nu sunt tocmai cutia neagră prognoze. La transformarea datelor în ts()
Un obiect din seria de timp a furnizat în mod explicit informații despre sezonalitate. Se pare că TimeGPT a dedus aceste informații din datele personajelor.
Afișați codul
RMSE <- function(m, o){sqrt(mean((m - o)^2))} rms_names <- c("tgpt", "arima", "ets", "prophet") rms_fcst <- array(NA_real_, dim = 4, dimnames = list(rms_names)) rms_fcst(1) <- RMSE(fcst_df2$tgpt_fcst, fcst_df2$elec_actual) rms_fcst(2) <- RMSE(fcst_df2$arima_fcst, fcst_df2$elec_actual) rms_fcst(3) <- RMSE(fcst_df2$ets_fcst, fcst_df2$elec_actual) rms_fcst(4) <- RMSE(fcst_df2$prophet_fcst, fcst_df2$elec_actual) rms_fcst
tgpt arima ets prophet 6.601752 4.966623 9.355767 14.948709
Câteva gânduri finale
Este clar că modelul TimeGPT a crescut jocul pentru previziunile seriilor de timp Black-Box. Este sigur că va deveni un instrument puternic pentru lucrări exploratorii cu serii de timp mari și pentru compararea mai multor serii de timp. Poate deveni Go-to Instrument de prognoză de bază pentru o gamă largă de proiecte de serii de timp. Mai mult, mă aștept ca experții din seria de timp care pot regla profetul și modelele mai tradiționale de serii de timp vor putea dezvolta o oarecare intuiție cu privire la ceea ce face TimeGPT prin evaluarea comportamentului său în raport cu aceste modele.
Sunt conștient de faptul că această mică postare ar fi putut ridica mai multe întrebări decât a răspuns. Dacă da, vă rugăm să încercați mâna la elaborarea unor probleme ridicate. Am fi foarte fericiți să luăm în considerare postările din seria de timp pentru publicarea pe lucrările R.
În cele din urmă, pentru o analiză mai sofisticată a acestor serii, care se ocupă de aspectele lor multisasonalii, consultați tutorialul privind prognoza de încărcare a energiei electrice. Și, pentru câteva idei despre cum să valorificăm LLM -urile „obișnuite” pentru prognoza seriei de timp, aruncați o privire la a doua jumătate a discuției pe care Bryan Lewis a oferit -o lui Nyhackr în aprilie 2024.
Confirmare
Multe mulțumiri profesorului Rob Hyndman pentru semnalizarea erorii obiectului din seria de timp ARIMA descrisă mai sus și pentru a sugera cu generozitate alternative care au dus la rezolvarea descrisă mai sus. Orice erori rămase în acest post sunt toate ale mele.