Nach dem Lesen diesen Blog-Beitrag über Bayes'sche strukturelle Zeitreihenmodelle , wollte ich die Implementierung im Kontext eines Problems betrachten, für das ich zuvor ARIMA verwendet hatte.
Ich habe einige Daten mit einigen bekannten (aber lauten) saisonalen Komponenten - es gibt definitiv jährliche, monatliche und wöchentliche Komponenten dazu und auch einige Effekte aufgrund besonderer Tage (wie bundesstaatliche oder religiöse Feiertage).
Ich habe das bsts
Paket verwendet, um dies zu implementieren, und soweit ich weiß, habe ich nichts falsch gemacht, obwohl die Komponenten und die Vorhersage einfach nicht so aussehen, wie ich es erwartet hätte. Mir ist nicht klar, ob meine Implementierung falsch, unvollständig oder auf andere Weise problematisch ist.
Die Vollzeitserie sieht folgendermaßen aus:
Ich kann das Modell auf einer Teilmenge der Daten trainieren, und das Modell sieht im Allgemeinen in Bezug auf die Anpassung gut aus (Grafik unten). Der Code, mit dem ich das mache, ist hier:
library(bsts)
predict_length = 90
training_cut_date <- '2015-05-01'
test_cut_date <- as.Date(training_cut_date) + predict_length
df = read.csv('input.tsv', sep ='\t')
df$date <- as.Date(as.character(df$date),format="%Y-%m-%d")
df_train = df[df$date < training_cut_date,]
yts <- xts(log10(df_train$count), order.by=df_train$date)
ss <- AddLocalLinearTrend(list(), yts)
ss <- AddSeasonal(ss, yts, nseasons = 7)
ss <- AddSeasonal(ss, yts, nseasons = 12)
ss <- AddNamedHolidays(ss, named.holidays = NamedHolidays(), yts)
model <- bsts(yts, state.specification = ss, niter = 500, seed=2016)
Das Modell sieht vernünftig aus:
Aber wenn ich die Vorhersage zeichne, ist zum einen der Trend völlig falsch und zum anderen wächst die Unsicherheit SEHR schnell - bis zu dem Punkt, an dem ich das Unsicherheitsband nicht mehr auf demselben Diagramm wie die Vorhersagen anzeigen kann, ohne die y-Achse auf einem Logbuch zu machen. Rahmen. Der Code für diesen Teil ist hier:
burn <- SuggestBurn(0.1, model)
pred <- predict(model, horizon = predict_length, burn = burn, quantiles = c(.025, .975))
Die reine Vorhersage sieht folgendermaßen aus:
Wenn Sie dann auf die ursprüngliche Verteilung zurückskalieren (wobei die gepunktete Linie den Übergang vom Training zur Vorhersage darstellt, liegen die Probleme auf der Hand:
Ich habe versucht, mehr saisonale Trends hinzuzufügen, saisonale Trends zu entfernen, einen AR-Begriff hinzuzufügen, den AddLocalLinearModel in AddGeneralizedLocalLinearTrend und einige andere Dinge zum Optimieren des Modells zu ändern, aber nichts hat die Probleme gelöst und die Vorhersagen aussagekräftiger gemacht. In einigen Fällen ändert sich die Richtung, so dass die Vorhersage in Abhängigkeit von der Zeit weiter zunimmt, anstatt auf 0 zu fallen. Ich verstehe definitiv nicht, warum das Modell auf diese Weise zusammenbricht. Anregungen wären sehr willkommen.
Antworten:
Steve Scott hier. Ich habe das bsts-Paket geschrieben. Ich habe ein paar Vorschläge für Sie. Erstens tun Ihre saisonalen Komponenten nicht das, was Sie denken. Ich denke, Sie haben tägliche Daten, weil Sie versuchen, eine 7-Jahreszeiten-Komponente hinzuzufügen, die korrekt funktionieren sollte. Sie haben jedoch angegeben, dass sich Ihre jährliche Saisonkomponente alle 12 Tage wiederholen soll. Das Abrufen einer monatlichen saisonalen Komponente mit täglichen Daten ist etwas schwierig, aber Sie können eine 52-wöchige saisonale Komponente bis zum durchführen
AddSeasonal(..., nseasons = 52, season.duration = 7)
.Das
seasonal.duration
Argument sagt dem Modell, wie viele Zeitpunkte jede Saison dauern soll. Dasnseasons
Argument sagt ihm, wie viele Jahreszeiten in einem Zyklus sind. Die Gesamtanzahl der Zeitpunkte in einem Zyklus beträgtseason.duration * nseasons
.Der zweite Vorschlag ist, dass Sie über ein anderes Trendmodell nachdenken möchten. Das
LocalLinearTrend
Modell ist sehr flexibel, aber diese Flexibilität kann sich als unerwünschte Varianz in langfristigen Prognosen zeigen. Es gibt einige andere Trendmodelle, die etwas mehr Struktur enthalten.GeneralizedLocalLinearTrend
(Entschuldigung für den nicht beschreibenden Namen) Angenommen, die "Steigungs" -Komponente des Trends ist ein AR1-Prozess anstelle eines zufälligen Gehens. Dies ist meine Standardoption, wenn ich weit in die Zukunft prognostizieren möchte. Der größte Teil Ihrer Zeitreihenvariationen scheint saisonbedingt zu sein. Versuchen Sie es alsoAddLocalLevel
oder versuchen Sie es sogarAddAr
stattdessenAddLocalLinearTrend
.Wenn Sie im Allgemeinen seltsame Prognosen erhalten und herausfinden möchten, welcher Teil des Modells schuld ist, versuchen Sie schließlich
plot(model, "components")
, das Modell in die von Ihnen angeforderten Einzelteile zu zerlegen.quelle
Ich denke du kannst auch die Voreinstellung brennen ändern. Da ich bsts verwendet habe, habe ich mit MAPE als Statistik für die Wartezeit ein Raster mit Brenn- und Niterwerten erstellt. Versuchen Sie auch, stattdessen AddStudentLocalLinearTrend zu verwenden, wenn Ihre Daten große Abweichungen aufweisen, damit das Modell solche Abweichungen erwartet
quelle