Vorhersagen aus dem BSTS-Modell (in R) scheitern vollständig

15

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 bstsPaket 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:

Vollständige Daten

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:

Modellgrundstück

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:

reine Vorhersage

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:

volle Distribution

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.

anthr
quelle
2
Warum postest du deine Daten nicht und ich werde versuchen zu helfen? Ich werde nicht in der Lage sein zu beantworten, warum das Modell zusammenbricht, da ich diesen Ansatz nicht verwende, da er zu viele Annahmen enthält. Bitte sei genau, wie viele Werte einbehalten wurden, das Startdatum und das Herkunftsland.
IrishStat
Vielen Dank für Ihren Kommentar. Ich habe die Rohdaten hier hochgeladen, für den Fall, dass Sie Zeit haben, einen Blick darauf zu werfen. Die Daten reichen von Anfang 2013 bis Ende dieses Jahres. Ich habe auch versucht, mit einem ARIMA-Modell zu prognostizieren, aber die Vorhersagen daraus stimmten auch nicht mit den Hold-out-Daten überein. Die Hold-out-Daten sind im Grunde genommen nur ein Bruchteil von 2015 oder 2016, je nachdem, wie viele Trainingsdaten ich verwenden wollte.
Anthr
Ich habe ein Problem beim Herunterladen. Bitte senden Sie eine CSV-Datei an meine E-Mail-Adresse
IrishStat

Antworten:

26

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.durationArgument sagt dem Modell, wie viele Zeitpunkte jede Saison dauern soll. Das nseasonsArgument sagt ihm, wie viele Jahreszeiten in einem Zyklus sind. Die Gesamtanzahl der Zeitpunkte in einem Zyklus beträgt season.duration * nseasons.

Der zweite Vorschlag ist, dass Sie über ein anderes Trendmodell nachdenken möchten. Das LocalLinearTrendModell 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 also AddLocalLeveloder versuchen Sie es sogarAddAr stattdessen AddLocalLinearTrend.

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.

Steve Scott
quelle
Zu Ihrer Information: Ich habe sehr ähnliche Probleme mit meinen Daten, was auch täglich vorkommt. Ich habe alle Ihre hier aufgeführten Vorschläge umgesetzt und keiner scheint zu helfen.
ZakJ
1
@Steve Scott Tut mir leid, dass ich Sie störe, Steve. Ich möchte Sie Folgendes fragen: Wenn ich versuche, mehrere Zeitreihen zu modellieren und mich in einem hierarchisch gemischten Modell-Framework befinde, kann ich dies mit Ihrem Paket modellieren? Übrigens: Vielen Dank für Ihr Paket!
Tommaso Guerrini
4

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

Elderkm2012
quelle
1
War in meinem Fall hilfreich, als ich nur wenige Datenpunkte hatte (20)
SCallan