Seite 1 von 1

Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Do Sep 26, 2019 1:04 pm
von ccleon
Hallo,

ich bearbeite für meine Masterarbeit das Thema Nachfrageprognosen und habe dazu eine sehr wichtige Frage und hoffe, dass mir jemand helfen kann.

Ich arbeite derzeit mit dem R Package "Prophet". Hierbei kann man z.B. historische Nachfragedaten in R importieren und das Programm berechnet anhand dieser historischen Daten dann Prognosen für zukünftige Perioden. Für diese zukünftigen Perioden wird sowohl ein erwarteter Nachfragewert (yhat) berechnet, als auch ein Fehlerintervall (80% Niveau, Wert kann angepasst werden) mit einem unteren Intervallwert (yhat_lower) und einem oberen Intervallwert (yhat_upper). Prophet berechnet dieses Intervall durch Monte-Carlo-Simulation anhand von 1000 Simulationswerten. Das Intervall sagt dann aus, dass 80% (bzw. je nach gewünschtem Niveau) der Simulationswerte in diesem Intervall liegen.

Das ganze geschieht auf Tagesbasis und ich habe im Anhang einen Beispiel-Screenshot von den berechneten Prognosen beigefügt, für jeden Tag ist dort ein Prognosewert und ein Fehlterintervall berechnet wurden. (Anmerkung: Die unteren Intervallwerte sind in der Regel negativ, es gibt zwar keine negativen Nachfragen aber hierbei würde es dann z.B. mehr Retourlieferungen geben als normale Lieferungen, es liegt also kein Fehler vor)

Mein Problem ist nun: Ich möchte diese Prognosen nicht auf Tagesbasis sondern auf Wochenbasis haben. Dazu kann ich natürlich ganz leicht die erwarteten Prognosewerte jeweils für 7 Tage aufsummieren und habe die Prognosewerte für jeweils eine Woche. Jedoch kann ich die Fehlterintervalle natürlich nicht einfach so aufsummieren und meine Frage ist nun, wie ich die Fehlterintervalle auf Tagesbasis aggregieren kann hin zu Wochenbasis.

In einem anderen Forum hat jemand genau die gleiche Frage gehabt wie ich und dazu auch einen Lösungsvorschlag bekommen (https://github.com/facebook/prophet/issues/426), nur leider hat dieser jemand das "Prophet" Package nicht für R sondern für Python benutzt und da ich leider generell nur ganz geringe Programmierkenntnisse habe und mich mit Python auch gar nicht auskenne, konnte ich diese Antwort nicht für mich nutzen und den Code nicht ausprobieren. Ich habe nur verstanden, dass man wieder mit Simulationen vorgehen sollte.

Ich bin mir nicht ganz sicher, ob mir jemand bei diesem Problem helfen kann, ohne genauere Kenntnisse von dem "Prophet" Package zu haben, aber ich bin auf jedenfall für jede Hilfe/ jeden Codevorschlag usw. sehr dankbar und kann bei Nachfragen auch gerne weitere Infos geben.

Vielen Dank schonmal!
LG Leon

Re: Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Sa Sep 28, 2019 12:18 pm
von databraineo
Hallo Leon,

der Link zum Python-Code war hilfreich, denn die beiden Sprachen haben im Datenanalyse-Bereich viele Ähnlichkeiten. Aber ein bisschen anders ist es natürlich schon.

Wenn ich es richtig verstanden habe, dann werden die wöchentlichen yhat_lower und yhat_upper als 10%- bzw. 90%-Perzentil der gesampelten Werte berechnet.

In R könnte das dann so aussehen:

Code: Alles auswählen

library(prophet)
library(dplyr)
library(tidyr)

history <- data.frame(ds = seq(as.Date('2015-01-01'), as.Date('2016-01-01'), by ='d'),
                      y = sin(1:366/200) + rnorm(366)/10)
m <- prophet(history)

# data.frame mit den gwünschten Daten
df <- data.frame(ds = seq(as.Date("2019-01-01"), Sys.Date(), by="d"))
# Kalenderwoche ergänzen
df$week <- format(df$ds, "%Y-%W")

# Vorhersage-samples mit dem Modell
samples <- predictive_samples(m, df)
# die gesampelten yhats zum data.frame hinzufügen
df <- cbind(df,as.data.frame(samples$yhat))

# umwandeln in einen Längsdatensatz (Kontenmodell) 
# Achtung: pivot_longer ist erst in den neuesten Versionen von tidyr enthalten. Alternativen sind gather oder melt
dfLong <- pivot_longer(df, cols = starts_with("V"), names_to = "sample")

# hier passiert das eigentliche Aggregieren
# yhat ist der Mittelwert der täglichen Mittelwerte
# yhat_lower/yhat_upper sind die 10%-/90%-Perzentile des Samples
weekly_predict <- dfLong %>% 
  group_by(week) %>% 
  summarize(yhat = mean(value),
            yhat_lower = quantile(value,0.1),
            yhat_upper = quantile(value,0.9))
Viele Grüße,
Holger

Re: Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Di Okt 01, 2019 5:02 pm
von ccleon
databraineo hat geschrieben: Sa Sep 28, 2019 12:18 pm Hallo Leon,

der Link zum Python-Code war hilfreich, denn die beiden Sprachen haben im Datenanalyse-Bereich viele Ähnlichkeiten. Aber ein bisschen anders ist es natürlich schon.

Wenn ich es richtig verstanden habe, dann werden die wöchentlichen yhat_lower und yhat_upper als 10%- bzw. 90%-Perzentil der gesampelten Werte berechnet.

In R könnte das dann so aussehen:

Code: Alles auswählen

library(prophet)
library(dplyr)
library(tidyr)

history <- data.frame(ds = seq(as.Date('2015-01-01'), as.Date('2016-01-01'), by ='d'),
                      y = sin(1:366/200) + rnorm(366)/10)
m <- prophet(history)

# data.frame mit den gwünschten Daten
df <- data.frame(ds = seq(as.Date("2019-01-01"), Sys.Date(), by="d"))
# Kalenderwoche ergänzen
df$week <- format(df$ds, "%Y-%W")

# Vorhersage-samples mit dem Modell
samples <- predictive_samples(m, df)
# die gesampelten yhats zum data.frame hinzufügen
df <- cbind(df,as.data.frame(samples$yhat))

# umwandeln in einen Längsdatensatz (Kontenmodell) 
# Achtung: pivot_longer ist erst in den neuesten Versionen von tidyr enthalten. Alternativen sind gather oder melt
dfLong <- pivot_longer(df, cols = starts_with("V"), names_to = "sample")

# hier passiert das eigentliche Aggregieren
# yhat ist der Mittelwert der täglichen Mittelwerte
# yhat_lower/yhat_upper sind die 10%-/90%-Perzentile des Samples
weekly_predict <- dfLong %>% 
  group_by(week) %>% 
  summarize(yhat = mean(value),
            yhat_lower = quantile(value,0.1),
            yhat_upper = quantile(value,0.9))
Viele Grüße,
Holger
Hallo,

@databraineo : vielen Dank für deine Antwort, dies hat mir geholfen und ich habe es nun hinbekommen :)

Ich hätte nun noch eine Frage, wie ich die Prognosewerte zusammen mit den Intervallwerten in einem Diagramm darstellen kann. Und zwar habe ich jetzt ein Data Frame mit 3 Spalten (Prognosewert, 10% Perzentil Wert, 90% Perzentil Wert) und ich möchte ein Diagramm haben, welches in etwa so aussieht:
Forecast interval.PNG
Gibt es da eine simple Möglichkeit?

Vielen Dank nochmals! :)

Re: Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Di Okt 01, 2019 10:47 pm
von EDi
das macht ggplot2::geom_ribbon ziemlich einfach! Here ein Beispiel (letzer plot): https://ggplot2.tidyverse.org/reference/geom_ribbon.html

Re: Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Mi Okt 02, 2019 11:43 am
von ccleon
EDi hat geschrieben: Di Okt 01, 2019 10:47 pm das macht ggplot2::geom_ribbon ziemlich einfach! Here ein Beispiel (letzer plot): https://ggplot2.tidyverse.org/reference/geom_ribbon.html
Hallo, danke, ich denke das ist genau das was ich brauche.

Ich habe versucht das Beispiel auf meinen Datenframe zu übertragen und habe es aber leider nicht ganz hinbekommen.

Ich habe ein Datenframe "wochenprognose" mit 4 Spalten (Woche, Prognose, ymin, ymax) und habe diese beiden Code Zeilen probiert:

Code: Alles auswählen

p <- ggplot(wochenprognose, aes(Woche))
p + geom_ribbon(aes(ymin = wochenprognose$ymin, ymax = wochenprognose$ymax), fill = "grey70") + geom_line(aes(y = wochenprognose$Prognose))
Ich bekomme die Meldung: "geom_path: Each group consists of only one observation. Do you need to adjust the group aesthetic?"

Wo liegt der Fehler bei mir?

VIelen Dank nochmals!

Re: Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Mi Okt 02, 2019 9:58 pm
von EDi
Keine '$' in ggplots aes verwenden!

Und ein reproduzierbares Beispiel posten...

Re: Fehlerintervall für mehrere Perioden aggregieren

Verfasst: Sa Okt 05, 2019 5:19 pm
von ccleon
Ein kurzes Update:

Mein Code von oben hatte nur nicht funktioniert, da ich einen blöden Fehler gemacht und mich vertippt hatte (falsche Bezeichnungen nach den "$"verwendet) Nach Korrektur hat alles gepasst.

Danke nochmal für die Hilfe! :)

LG