Sie sollten das Vorhersagepaket verwenden , das alle diese Modelle (und mehr) unterstützt und deren Anpassung zum Kinderspiel macht:
library(forecast)
x <- AirPassengers
mod_arima <- auto.arima(x, ic='aicc', stepwise=FALSE)
mod_exponential <- ets(x, ic='aicc', restrict=FALSE)
mod_neural <- nnetar(x, p=12, size=25)
mod_tbats <- tbats(x, ic='aicc', seasonal.periods=12)
par(mfrow=c(4, 1))
plot(forecast(mod_arima, 12), include=36)
plot(forecast(mod_exponential, 12), include=36)
plot(forecast(mod_neural, 12), include=36)
plot(forecast(mod_tbats, 12), include=36)
Ich würde davon abraten, die Daten vor dem Anpassen Ihres Modells zu glätten. Ihr Modell wird von Natur aus versuchen, die Daten zu glätten, sodass das Vorglätten die Sache nur kompliziert macht.
Bearbeiten basierend auf neuen Daten:
Es sieht tatsächlich so aus, als ob Arima eines der schlechtesten Modelle ist, die Sie für dieses Trainings- und Test-Set ausgewählt haben.
Ich habe Ihre Daten in einem Dateiaufruf gespeichert coil.csv
, in R geladen und in ein Trainings- und Test-Set aufgeteilt:
library(forecast)
dat <- read.csv('~/coil.csv')
x <- ts(dat$Coil, start=c(dat$Year[1], dat$Month[1]), frequency=12)
test_x <- window(x, start=c(2012, 3))
x <- window(x, end=c(2012, 2))
Als nächstes passe ich eine Reihe von Zeitreihenmodellen an: Arima, exponentielle Glättung, neuronales Netzwerk, TBats, Fledermäuse, saisonale Zerlegung und strukturelle Zeitreihen:
models <- list(
mod_arima = auto.arima(x, ic='aicc', stepwise=FALSE),
mod_exp = ets(x, ic='aicc', restrict=FALSE),
mod_neural = nnetar(x, p=12, size=25),
mod_tbats = tbats(x, ic='aicc', seasonal.periods=12),
mod_bats = bats(x, ic='aicc', seasonal.periods=12),
mod_stl = stlm(x, s.window=12, ic='aicc', robust=TRUE, method='ets'),
mod_sts = StructTS(x)
)
Dann habe ich einige Vorhersagen gemacht und mit dem Testset verglichen. Ich habe eine naive Vorhersage eingefügt, die immer eine flache, horizontale Linie vorhersagt:
forecasts <- lapply(models, forecast, 12)
forecasts$naive <- naive(x, 12)
par(mfrow=c(4, 2))
for(f in forecasts){
plot(f)
lines(test_x, col='red')
}
Wie Sie sehen, ist das Arima-Modell im Trend verkehrt, aber ich mag das Aussehen des "Basic Structural Model".
Schließlich habe ich die Genauigkeit jedes Modells am Testgerät gemessen:
acc <- lapply(forecasts, function(f){
accuracy(f, test_x)[2,,drop=FALSE]
})
acc <- Reduce(rbind, acc)
row.names(acc) <- names(forecasts)
acc <- acc[order(acc[,'MASE']),]
round(acc, 2)
ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
mod_sts 283.15 609.04 514.46 0.69 1.27 0.10 0.77 1.65
mod_bats 65.36 706.93 638.31 0.13 1.59 0.12 0.85 1.96
mod_tbats 65.22 706.92 638.32 0.13 1.59 0.12 0.85 1.96
mod_exp 25.00 706.52 641.67 0.03 1.60 0.12 0.85 1.96
naive 25.00 706.52 641.67 0.03 1.60 0.12 0.85 1.96
mod_neural 81.14 853.86 754.61 0.18 1.89 0.14 0.14 2.39
mod_arima 766.51 904.06 766.51 1.90 1.90 0.14 0.73 2.48
mod_stl -208.74 1166.84 1005.81 -0.52 2.50 0.19 0.32 3.02
Die verwendeten Metriken sind in Hyndman, RJ und Athanasopoulos, G. (2014) "Forecasting: Principles and Practice" beschrieben , die zufällig auch die Autoren des Forecast-Pakets sind. Ich empfehle Ihnen nachdrücklich, ihren Text zu lesen: Er ist kostenlos online verfügbar. Die strukturelle Zeitreihe ist das beste Modell nach mehreren Metriken, einschließlich MASE, der Metrik, die ich für die Modellauswahl am meisten bevorzuge.
Eine letzte Frage ist: Hat das Strukturmodell bei diesem Testsatz Glück gehabt? Eine Möglichkeit, dies zu beurteilen, ist die Betrachtung von Trainingssatzfehlern. Trainingssatzfehler sind weniger zuverlässig als Testsatzfehler (da sie überanpassbar sein können), aber in diesem Fall hat das Strukturmodell immer noch die Nase vorn:
acc <- lapply(forecasts, function(f){
accuracy(f, test_x)[1,,drop=FALSE]
})
acc <- Reduce(rbind, acc)
row.names(acc) <- names(forecasts)
acc <- acc[order(acc[,'MASE']),]
round(acc, 2)
ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
mod_sts -0.03 0.99 0.71 0.00 0.00 0.00 0.08 NA
mod_neural 3.00 1145.91 839.15 -0.09 2.25 0.16 0.00 NA
mod_exp -82.74 1915.75 1359.87 -0.33 3.68 0.25 0.06 NA
naive -86.96 1936.38 1386.96 -0.34 3.75 0.26 0.06 NA
mod_arima -180.32 1889.56 1393.94 -0.74 3.79 0.26 0.09 NA
mod_stl -38.12 2158.25 1471.63 -0.22 4.00 0.28 -0.09 NA
mod_bats 57.07 2184.16 1525.28 0.00 4.07 0.29 -0.03 NA
mod_tbats 62.30 2203.54 1531.48 0.01 4.08 0.29 -0.03 NA
(Beachten Sie, dass das neuronale Netzwerk übermäßig gut funktioniert, wenn das Trainingsset und das Testset schlecht sind.)
Schließlich wäre es eine gute Idee, alle diese Modelle gegenseitig zu validieren, beispielsweise durch Schulung von 2008 bis 2009 / Testen von 2010, Training von 2008 bis 2010 / Testen von 2011, Training von 2008 bis 2011 / Testen von 2012, Training am 2008-2012 / Testen am 2013 und Mitteln von Fehlern über alle diese Zeiträume. Wenn Sie diesen Weg beschreiten möchten, habe ich ein teilweise vollständiges Paket für die Validierung von Zeitreihenmodellen auf github , das Sie gerne ausprobieren und mir Feedback / Pull-Anfragen zu folgenden Themen geben können:
devtools::install_github('zachmayer/cv.ts')
library(cv.ts)
Edit 2: Mal sehen, ob ich mich erinnere, wie ich mein eigenes Paket benutze!
Installieren und laden Sie zunächst das Paket von github (siehe oben). Überprüfen Sie dann einige Modelle (unter Verwendung des vollständigen Datensatzes):
library(cv.ts)
x <- ts(dat$Coil, start=c(dat$Year[1], dat$Month[1]), frequency=12)
ctrl <- tseriesControl(stepSize=1, maxHorizon=12, minObs=36, fixedWindow=TRUE)
models <- list()
models$arima = cv.ts(
x, auto.arimaForecast, tsControl=ctrl,
ic='aicc', stepwise=FALSE)
models$exp = cv.ts(
x, etsForecast, tsControl=ctrl,
ic='aicc', restrict=FALSE)
models$neural = cv.ts(
x, nnetarForecast, tsControl=ctrl,
nn_p=6, size=5)
models$tbats = cv.ts(
x, tbatsForecast, tsControl=ctrl,
seasonal.periods=12)
models$bats = cv.ts(
x, batsForecast, tsControl=ctrl,
seasonal.periods=12)
models$stl = cv.ts(
x, stl.Forecast, tsControl=ctrl,
s.window=12, ic='aicc', robust=TRUE, method='ets')
models$sts = cv.ts(x, stsForecast, tsControl=ctrl)
models$naive = cv.ts(x, naiveForecast, tsControl=ctrl)
models$theta = cv.ts(x, thetaForecast, tsControl=ctrl)
(Beachten Sie, dass ich die Flexibilität des neuronalen Netzwerkmodells reduziert habe, um eine Überanpassung zu verhindern.)
Sobald wir die Modelle angepasst haben, können wir sie mit MAPE vergleichen (cv.ts unterstützt MASE noch nicht):
res_overall <- lapply(models, function(x) x$results[13,-1])
res_overall <- Reduce(rbind, res_overall)
row.names(res_overall) <- names(models)
res_overall <- res_overall[order(res_overall[,'MAPE']),]
round(res_overall, 2)
ME RMSE MAE MPE MAPE
naive 91.40 1126.83 961.18 0.19 2.40
ets 91.56 1127.09 961.35 0.19 2.40
stl -114.59 1661.73 1332.73 -0.29 3.36
neural 5.26 1979.83 1521.83 0.00 3.83
bats 294.01 2087.99 1725.14 0.70 4.32
sts -698.90 3680.71 1901.78 -1.81 4.77
arima -1687.27 2750.49 2199.53 -4.23 5.53
tbats -476.67 2761.44 2428.34 -1.23 6.10
Autsch. Es scheint, dass unsere strukturelle Prognose Glück hatte. Langfristig liefert die naive Prognose die besten Prognosen, gemittelt über einen Zeitraum von 12 Monaten (das Arima-Modell ist immer noch eines der schlechtesten Modelle). Vergleichen wir die Modelle an jedem der 12 Prognosehorizonte und sehen wir, ob eines davon jemals das naive Modell übertrifft:
library(reshape2)
library(ggplot2)
res <- lapply(models, function(x) x$results$MAPE[1:12])
res <- data.frame(do.call(cbind, res))
res$horizon <- 1:nrow(res)
res <- melt(res, id.var='horizon', variable.name='model', value.name='MAPE')
res$model <- factor(res$model, levels=row.names(res_overall))
ggplot(res, aes(x=horizon, y=MAPE, col=model)) +
geom_line(size=2) + theme_bw() +
theme(legend.position="top") +
scale_color_manual(values=c(
"#1f78b4", "#ff7f00", "#33a02c", "#6a3d9a",
"#e31a1c", "#b15928", "#a6cee3", "#fdbf6f",
"#b2df8a")
)
Bezeichnenderweise wählt das exponentielle Glättungsmodell immer das naive Modell (die orange Linie und die blaue Linie überlappen sich zu 100%). Mit anderen Worten, die naive Prognose der Coil-Preise für den nächsten Monat entspricht den Coil-Preisen für diesen Monat und ist genauer (an fast jedem Prognosehorizont) als 7 äußerst ausgefeilte Zeitreihenmodelle. Wenn Sie keine geheimen Informationen haben, die der Spulenmarkt noch nicht kennt, wird es äußerst schwierig sein , die naive Spulenpreisprognose zu übertreffen .
Es ist nie die Antwort, die irgendjemand hören möchte, aber wenn die Genauigkeit der Vorhersage Ihr Ziel ist, sollten Sie das genaueste Modell verwenden. Verwenden Sie das naive Modell.