2.2 Deskriptive Statistik
# Einlesen und Öffnen des Datensatzes
test <- read.csv("~/Desktop/Uni/7. Semester/David BA/demand-forecasting-kernels-only/test.csv")
train <- read.csv("~/Desktop/Uni/7. Semester/David BA/demand-forecasting-kernels-only/train.csv")
#Ergründung der Struktur der Trainingsdaten
str(train)
## 'data.frame': 913000 obs. of 4 variables:
## $ date : chr "2013-01-01" "2013-01-02" "2013-01-03" "2013-01-04" ...
## $ store: int 1 1 1 1 1 1 1 1 1 1 ...
## $ item : int 1 1 1 1 1 1 1 1 1 1 ...
## $ sales: int 13 11 14 13 10 12 10 9 12 9 ...
#Ergründung der Struktur der Testdaten
str(test)
## 'data.frame': 45000 obs. of 4 variables:
## $ id : int 0 1 2 3 4 5 6 7 8 9 ...
## $ date : chr "2018-01-01" "2018-01-02" "2018-01-03" "2018-01-04" ...
## $ store: int 1 1 1 1 1 1 1 1 1 1 ...
## $ item : int 1 1 1 1 1 1 1 1 1 1 ...
#Summary-Tabelle
stargazer(train, type="text")
##
## ===========================================================
## Statistic N Mean St. Dev. Min Pctl(25) Pctl(75) Max
## -----------------------------------------------------------
## store 913,000 5.500 2.872 1 3 8 10
## item 913,000 25.500 14.431 1 13 38 50
## sales 913,000 52.250 28.801 0 30 70 231
## -----------------------------------------------------------
#Aggregation nach Store
agg = aggregate(train,
by = list(train$store),
FUN = mean)
#Durchschnittliche Verkäufe pro Store pro Tag
ggplot(agg, aes(x = store, y = sales, fill = store)) +
geom_bar(stat = "identity", fill = "steelblue")+
geom_text(aes(label=round(sales)), color="white", vjust=1.5, size=3.5)+
theme_classic() +
labs(x = "Filiale",
y = "durchschn. Verkäufe",
title = "Durchschnittliche Verkäufe pro Tag") +
scale_x_discrete(name = "Filiale(store)",
limits = c("1", "2", "3", "4", "5",
"6", "7", "8", "9", "10"))

#Aggregation nach item
agg2 = aggregate(train,
by = list(train$item),
FUN = mean)
#Aufteilung in 4 Gruppen für übersichtliche Diagramme
agg2$group <- as.numeric(cut(agg2$item, 4))
#Erstellung Diagramm: durchschn. Verkäufe pro Item pro Tag
ggplot(agg2, aes(x = factor(item), y = sales)) +
geom_bar(stat = "identity", fill = "steelblue") +
geom_text(aes(label=round(sales)),color="white", vjust=1.5, size=2.5) +
theme(axis.text.x = element_text( vjust = 0.5)) +
labs(x = "item",
y = "durchschn. Verkäufe",
title = "Durchschnittliche Verkäufe pro item pro Tag") +
facet_wrap(~group, ncol = 2, scales = "free_x")

#Histogramm von Sales (Häufigkeitsverteilung der sales)
ggplot(train, aes(x=sales))+
geom_histogram(fill="steelblue", alpha=.7)+
labs(x="sales", y="Häufigkeit", title="Histogramm von sales")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

2.3 Datenaufteilung
#Ähnlichkeiten der verschiedenen Zeitreihen
#Erstellung Zeitreihe store 2 & item 15
store2_item15 <- setDT(train)[store == 2 & item == 15]
ts_store2_item15 <- ts(store2_item15[,c("sales")],
start = c(2013,1),
frequency = 365)
#Erstellung Zeitreihe store 10 & item 6
store10_item6 <- setDT(train)[store == 10 & item == 6]
ts_store10_item6 <- ts(store10_item6[,c("sales")],
start = c(2013,1),
frequency = 365)
#Erstellung Zeitreihe store 4 & item 1
store4_item1 <- setDT(train)[store == 4 & item == 1]
ts_store4_item1 <- ts(store4_item1[,c("sales")],
start = c(2013,1),
frequency = 365)
#Erstellung Zeitreihe store 7 & item 12
store7_item12 <- setDT(train)[store == 7 & item == 12]
ts_store7_item12 <- ts(store7_item12[,c("sales")],
start = c(2013,1),
frequency = 365)
par(mfrow=c(2,2))
plot(ts_store2_item15, xlab="Jahr", ylab="durchschn. Verkäufe", main="store2_item15")
plot(ts_store10_item6, xlab="Jahr", ylab="durchschn. Verkäufe", main="store10_item6")
plot(ts_store4_item1, xlab="Jahr", ylab="durchschn. Verkäufe", main="store4_item1")
plot(ts_store7_item12, xlab="Jahr", ylab="durchschn. Verkäufe", main="store7_item12")

#Datenaufteilung 80/20
train_window =window(ts_store2_item15, start=2013, end=c(2016,365))
test_window = window(ts_store2_item15, start=2017, end=c(2017,365))
Trainingsdaten_80 <- ts(train_window, frequency = 365, start = c(2013,1))
plot(Trainingsdaten_80)

Testdaten_20 <- ts(test_window, frequency = 365, start = c(2017,1))
plot(Testdaten_20)

autoplot(Trainingsdaten_80, xlab="Jahr", ylab="durchschn. Verkäufe")+
autolayer(Testdaten_20)+
autolayer(Trainingsdaten_80)+
guides(colour=guide_legend(title="Daten"))

#Korrelogramm der Trainingsdaten
#Zeitreihenzerlung der Trainingsdaten
Korrelogramm_train <- ggAcf(ts_store2_item15)
plot(Korrelogramm_train)

plot(decompose(ts_store2_item15))

2.3 Anwendung der Prognosemodelle
2.3.1 Naive Prognose
#für kürzere Prognose h-Wert anpassen 3Monate: h=90
#Naive Prognose, h= Anzahl an Prognose-Perioden
naive_prognose <- naive(Trainingsdaten_80, h = 90, c(80, 95))
autoplot(naive_prognose)+
xlab("Jahr")+
ylab("durchschn. Verkäufe")

accuracy(naive_prognose, Testdaten_20)
## ME RMSE MAE MPE MAPE MASE
## Training set 0.01987663 24.13404 17.97464 -2.7204683 18.01048 0.8307543
## Test set 4.46666667 19.96775 16.28889 0.8087245 16.31557 0.7528420
## ACF1 Theil's U
## Training set -0.3884003 NA
## Test set 0.3594551 0.8731591
#Anzeige Prognosewerte
#dunkle Markierung: Zeigt an, wo der Wert in 80% der Fälle ist
#helle Markierung: Zeigt an, wo der Wert in 95% der Fälle ist
#show(naive_prognose) <- wegen Übersicht Befehl nicht durchgeführt
2.3.2 Naive Prognose (saisonal)
#Naive Prognose (saisonal), h= Anzahl an Prognose-Perioden
#Prognosewert = Wert der gleichen Saison aus Vorperiode
#für kürzere Prognose h-Wert anpassen 3Monate: h=90
naive_prognose_saisonal <- snaive(Trainingsdaten_80, h = 365, level=c(80,95))
autoplot(naive_prognose_saisonal,
xlab="Jahr",
ylab="durchschn. Verkäufe")

accuracy(naive_prognose_saisonal, Testdaten_20)
## ME RMSE MAE MPE MAPE MASE ACF1
## Training set 9.181735 26.37250 21.63653 5.546645 19.79364 1.0000000 -0.1512906
## Test set 4.778082 26.02591 20.19178 1.693608 16.83065 0.9332264 -0.2428726
## Theil's U
## Training set NA
## Test set 0.9787598
#Anzeige Prognosewerte
#dunkle Markierung: Zeigt an, wo der Wert in 80% der Fälle ist
#helle Markierung: Zeigt an, wo der Wert in 95% der Fälle ist
#show(naive_prognose_saisonal) <- wegen Übersicht Befehl nicht durchgeführt
2.3.3 einfache exponentielle Glättung
#einfache exponentielle Glättung
#für kürzere Prognose h-Wert anpassen 3 Monate: h=90
einf_exp_glättung_ts <- ses(Trainingsdaten_80, h=365, alpha=0.4, level=c(80,95))
autoplot(einf_exp_glättung_ts, xlab="Jahr", ylab="durchschn. Verkäufe",
title="Naive Prognose (saisonal) Store 2 Item 15")

#show(einf_exp_glättung_ts) <- Werte anzeigen lassen
accuracy(einf_exp_glättung_ts, Testdaten_20)
## ME RMSE MAE MPE MAPE MASE
## Training set 0.03897858 20.62337 16.04304 -3.018734 15.76091 0.7414792
## Test set 38.17736637 48.60660 40.50330 25.859420 28.98618 1.8719871
## ACF1 Theil's U
## Training set -0.007125855 NA
## Test set 0.608289250 1.713129
2.3.4 Holt-Winters-Verfahren
#gesamte Sicht start=2013 -> Fenster (2013-2017)
#Holt-Winters-Verfahren benötigt wöchentliche Sicht
#Window(), für bessere Skalierung der Grafik
windowtsDataWeekly <- window(Trainingsdaten_80, start= 2013, end = c(2016,365))
tsDataWeekly <- ts(windowtsDataWeekly, frequency = 7)
#für kürzere Prognose h-Wert anpassen 3 Monate: h=90
fit1 <- hw(tsDataWeekly, h=365, seasonal = "additive")
fit2 <- hw(tsDataWeekly, h=365, seasonal = "multiplicative")
autoplot(tsDataWeekly) +
autolayer(fit1, series="HW additive Prognosen", PI=FALSE) +
autolayer(fit2, series="HW multiplicative Prognosen", PI=FALSE) +
xlab("Woche") +
ylab("durchschn. Verkäufe") +
ggtitle("HW Prognose") +
guides(colour=guide_legend(title="Prognose"))

#für hw-Verfahren werden Testdaten wöchentlich benötigt
#start=209, da 4 Jahre * 52 Wochen = 208 (Trainingsdaten)
testDataWeekly <- ts(Testdaten_20, frequency = 7, start=209)
accuracy(fit1, testDataWeekly) #additiv HW
## ME RMSE MAE MPE MAPE MASE
## Training set -0.1104765 12.32162 9.686705 -1.229303 9.31917 0.7475453
## Test set 33.6494184 49.97770 39.569646 21.379560 28.81701 3.0536805
## ACF1 Theil's U
## Training set 0.05114907 NA
## Test set 0.51342671 1.775544
accuracy(fit2, testDataWeekly) #multiplikativ HW
## ME RMSE MAE MPE MAPE MASE
## Training set -0.01517778 11.98593 9.393619 -1.11151 8.980088 0.7249272
## Test set 36.54109705 50.37117 40.834554 23.92737 29.471798 3.1512963
## ACF1 Theil's U
## Training set 0.02684915 NA
## Test set 0.54487498 1.774124
#HoltWinters(windowtsDataWeekly)$alpha
#HoltWinters(windowtsDataWeekly)$beta
#HoltWinters(windowtsDataWeekly)$gamma
#tail(HoltWinters(windowtsDataWeekly)$fitted)
#show(fit1)
#show(fit2)
#Detailsicht start=2016 -> kleineres Fenster (2016-2017)
#Holt-Winters-Verfahren benötigt wöchentliche Sicht
#Window(), für bessere Skalierung der Grafik
windowtsDataWeekly <- window(Trainingsdaten_80, start= 2016, end= c(2016, 365))
tsDataWeekly <- ts(windowtsDataWeekly, frequency = 7)
#für kürzere Prognose h-Wert anpassen 3 Monate: h=90
fit1 <- hw(tsDataWeekly, h=365, seasonal = "additive")
fit2 <- hw(tsDataWeekly, h=365, seasonal = "multiplicative")
autoplot(tsDataWeekly) +
autolayer(fit1, series="HW additive Prognosen", PI=FALSE) +
autolayer(fit2, series="HW multiplicative Prognosen", PI=FALSE) +
xlab("Woche") +
ylab("durchschn. Verkäufe") +
ggtitle("HW Prognose") +
guides(colour=guide_legend(title="Prognose"))

2.3.5 Arima-Modell
#für kürzere Prognose h-Wert anpassen 3 Monate: h=90
Prognose_arima1 <- auto.arima(Trainingsdaten_80)
autoplot(forecast(Prognose_arima1, h=365), xlab = "Jahr", ylab= "durchschn. Verkäufe")

## Series: Trainingsdaten_80
## ARIMA(5,1,2)(0,1,0)[365]
##
## Coefficients:
## ar1 ar2 ar3 ar4 ar5 ma1 ma2
## -0.9110 -0.1920 -0.2059 -0.2456 0.0753 -0.1768 -0.7867
## s.e. 0.0386 0.0418 0.0412 0.0416 0.0329 0.0248 0.0237
##
## sigma^2 estimated as 512.9: log likelihood=-4967.91
## AIC=9951.83 AICc=9951.96 BIC=9991.81
accuracy(forecast(Prognose_arima1, h=365), Testdaten_20)
## ME RMSE MAE MPE MAPE MASE
## Training set 0.04294924 19.54138 12.90186 -2.031587 12.21522 0.5962997
## Test set -4.49933055 25.95744 18.64379 -6.087430 16.22927 0.8616809
## ACF1 Theil's U
## Training set 0.02394253 NA
## Test set -0.24256707 0.9260199
2.3.6 Prophet-Modell
#Erstellen Zeitreihe item15 store2
train_subset_store2_item15=subset(train,train$store==2 & train$item==15)
#Erstellung window mit Zeitraum 2013-2016
setDT(train_subset_store2_item15)
store_2_item15_fenster <- train_subset_store2_item15[date <= "2016-12-31"]
#Durchführung von Prophet-Modell 1Jahresprognose 2017-2018
stats=data.frame(y=store_2_item15_fenster$sales
,ds=store_2_item15_fenster$date)
stats=aggregate(stats$y,by=list(stats$ds),FUN=sum)
#head(stats)
colnames(stats)<- c("ds","y")
#für kürzere Prognose periods anpassen 3 Monate: periods = 90
model_prophet = prophet(stats)
## Disabling daily seasonality. Run prophet with daily.seasonality=TRUE to override this.
#summary(model_prophet)
future = make_future_dataframe(model_prophet, periods = 90)
forecast = predict(model_prophet, future)
plot(model_prophet, forecast, xlab="Jahr", ylab="durchschn. Verkäufe")

#mithilfe von Excel wurdeen die Prognosewerte extrahiert
#Laden und umbenennen der Excel
#Prophet_prognosewerte <- R_prophet_modell_forecast
#prophet_train_set<- ts(Prophet_prognosewerte, frequency = 365, start=c(2017,1))
#accuracy für 1 Jahr
#accuracy(prophet_train_set, Testdaten_20)
#accuracy 3 Monate
#Prophet_prognosewerte_3monate <- prophet_3monate_prognose
#prophet_train_set_3monate <- ts(Prophet_prognosewerte_3monate, frequency = 365,start=c(2017,1))
#accuracy(prophet_train_set_3monate, Testdaten_20)
2.3.7 Neuronale Netze
#für kürzere Prognose h-Wert anpassen 3 Monate: h=90
neuronales_netz1 <- nnetar(Trainingsdaten_80)
autoplot(forecast(neuronales_netz1, h=365), xlab = "Jahr", ylab = "durchschn. Verkäufe")

accuracy(forecast(neuronales_netz1, h=365), Testdaten_20)
## ME RMSE MAE MPE MAPE MASE
## Training set -0.006384656 4.531664 3.454613 -0.4259944 3.213893 0.1596658
## Test set -9.345518952 18.929416 15.211271 -9.4582690 13.251083 0.7030365
## ACF1 Theil's U
## Training set 0.03008802 NA
## Test set 0.44101031 0.8335747