Vous devez utiliser le package de prévision , qui prend en charge tous ces modèles (et plus) et facilite leur ajustement:
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)
Je déconseille de lisser les données avant d'adapter votre modèle. Votre modèle va par nature essayer de lisser les données, donc le pré-lissage ne fait que compliquer les choses.
Modifier en fonction des nouvelles données:
Il semble que l'arima soit l'un des pires modèles que vous puissiez choisir pour cet ensemble d'entraînement et de test.
J'ai enregistré vos données dans un appel de fichier coil.csv
, les ai chargées dans R et les ai divisées en un ensemble de formation et de test:
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))
Ensuite, j'adapte un tas de modèles de séries chronologiques: arima, lissage exponentiel, réseau neuronal, tbats, chauves-souris, décomposition saisonnière et séries chronologiques structurelles:
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)
)
Ensuite, j'ai fait quelques prévisions et comparé à l'ensemble de test. J'ai inclus une prévision naïve qui prédit toujours une ligne horizontale plate:
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')
}
Comme vous pouvez le voir, le modèle arima se trompe de tendance, mais j'aime un peu le look du "Basic Structural Model"
Enfin, j'ai mesuré la précision de chaque modèle sur l'ensemble de test:
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
Les métriques utilisées sont décrites dans Hyndman, RJ et Athanasopoulos, G. (2014) «Forecasting: Principles and Practice» , qui se trouvent également être les auteurs de l'ensemble de prévisions. Je vous recommande fortement de lire leur texte: il est disponible gratuitement en ligne. La série chronologique structurelle est le meilleur modèle selon plusieurs métriques, y compris MASE, qui est la métrique que j'ai tendance à préférer pour la sélection du modèle.
Une dernière question est: le modèle structurel a-t-il eu de la chance sur cet ensemble de test? Une façon d'évaluer cela consiste à examiner les erreurs des ensembles de formation. Les erreurs de l'ensemble de formation sont moins fiables que les erreurs de l'ensemble de test (car elles peuvent être trop ajustées), mais dans ce cas, le modèle structurel vient toujours en tête:
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
(Notez que le réseau de neurones est trop performant, performant sur l'ensemble d'entraînement et médiocrement sur l'ensemble de test)
Enfin, ce serait une bonne idée de contre-valider tous ces modèles, peut-être par une formation sur 2008-2009 / tests sur 2010, formation sur 2008-2010 / tests sur 2011, formation sur 2008-2011 / tests sur 2012, formation sur 2008-2012 / tests sur 2013 et moyenne des erreurs sur toutes ces périodes. Si vous souhaitez emprunter cette voie, j'ai un package partiellement complet pour les modèles de séries chronologiques à validation croisée sur github que j'aimerais que vous essayiez et que vous me fassiez part de vos commentaires / demandes de traction sur:
devtools::install_github('zachmayer/cv.ts')
library(cv.ts)
Edit 2: Voyons si je me souviens comment utiliser mon propre package!
Tout d'abord, installez et chargez le paquet depuis github (voir ci-dessus). Validez ensuite certains modèles (en utilisant l'ensemble de données complet):
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)
(Notez que j'ai réduit la flexibilité du modèle de réseau neuronal, pour essayer de l'empêcher de sur-adapter)
Une fois que nous avons ajusté les modèles, nous pouvons les comparer par MAPE (cv.ts ne prend pas encore en charge MASE):
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
Aie. Il semblerait que notre prévision structurelle ait eu de la chance. À long terme, la prévision naïve fait les meilleures prévisions, moyennées sur un horizon de 12 mois (le modèle arima est toujours l'un des pires modèles). Comparons les modèles à chacun des 12 horizons de prévision et voyons si l'un d'eux a déjà battu le modèle naïf:
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")
)
Fait révélateur, le modèle de lissage exponentiel sélectionne toujours le modèle naïf (la ligne orange et la ligne bleue se chevauchent à 100%). En d'autres termes, la prévision naïve des "prix des bobines du mois prochain sera la même que les prix des bobines de ce mois-ci" est plus précise (à presque tous les horizons de prévision) que 7 modèles de séries chronologiques extrêmement sophistiqués. Sauf si vous avez des informations secrètes que le marché des bobines ne connaît pas déjà, battre les prévisions de prix naïves des bobines sera extrêmement difficile .
Ce n'est jamais la réponse que quiconque veut entendre, mais si la précision des prévisions est votre objectif, vous devez utiliser le modèle le plus précis. Utilisez le modèle naïf.