Tüm bu modelleri (ve daha fazlasını) destekleyen ve bunları takmayı kolaylaştıran tahmin paketini kullanmalısınız :
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)
Modelinizi takmadan önce verileri düzeltmemenizi tavsiye ederim. Modeliniz doğal olarak verileri düzeltmeye çalışacaktır, bu nedenle ön düzeltme yalnızca işleri karmaşıklaştırır.
Yeni verilere göre düzenleme:
Aslında arima bu eğitim ve test seti için seçebileceğiniz en kötü modellerden biri gibi görünüyor.
Verilerinizi bir dosya görüşmesine kaydettim coil.csv
, R'ye yükledim ve bir eğitim ve test kümesine böldüm:
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))
Sonra bir dizi zaman serisi modeline uyuyorum: arima, üstel yumuşatma, sinir ağı, tbats, yarasalar, mevsimsel ayrışma ve yapısal zaman serileri:
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)
)
Sonra bazı tahminler yaptım ve test setiyle karşılaştırdım. Her zaman düz, yatay bir çizgi öngören saf bir tahmin ekledim:
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')
}
Gördüğünüz gibi, arima modeli eğilimi yanlış anlıyor, ancak "Temel Yapısal Model"
Son olarak, her modelin doğruluğunu test setinde ölçtüm:
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
Kullanılan metrikler , aynı zamanda tahmin paketinin yazarı olan Hyndman, RJ ve Athanasopoulos, G. (2014) "Tahmin: ilkeler ve uygulama" da açıklanmaktadır. Metinlerini okumanızı şiddetle tavsiye ederim: çevrimiçi olarak ücretsiz olarak kullanılabilir. Yapısal zaman serileri, model seçimi için tercih ettiğim metrik olan MASE de dahil olmak üzere birçok metrik için en iyi modeldir.
Son soru şudur: Yapısal model bu test setinde şanslı mıydı? Bunu değerlendirmenin bir yolu eğitim seti hatalarına bakmaktır. Eğitim seti hataları, test seti hatalarından daha az güvenilirdir (çünkü fazla uyum sağlayabilirler), ancak bu durumda yapısal model hala en üstte ortaya çıkar:
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
(Sinir ağının fazla çalıştığını, eğitim setinde mükemmel ve test setinde kötü performans gösterdiğini unutmayın)
Son olarak, belki de 2008-2009 / 2010'da test, 2008-2010'da test / 2011'de test, 2008-2011'de eğitim / 2012'de test, eğitim ile tüm bu modellerin çapraz doğrulanması iyi bir fikir olacaktır. 2008-2012 / 2013'te test edildi ve bu zaman dilimlerinin tamamında hataların ortalaması alındı. Bu rotaya inmek isterseniz , github'da zaman serisi modellerini çapraz doğrulamak için kısmen denemeyi ve bana geri bildirim / çekme istekleri vermenizi istediğim bir paketim var:
devtools::install_github('zachmayer/cv.ts')
library(cv.ts)
Edit 2: Kendi paketimi nasıl kullanacağımı hatırlayıp hatırlamadığımı görelim!
Her şeyden önce, paketi github'dan yükleyin ve yükleyin (yukarıya bakın). Ardından bazı modelleri çapraz doğrulayın (tam veri kümesini kullanarak):
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)
(Sinir ağı modelinin esnekliğini azalttığımı, aşırı sığmasını önlemeye yardımcı olmaya çalıştığımı unutmayın)
Modelleri sığdırdıktan sonra, MAPE ile karşılaştırabiliriz (cv.ts henüz MASE'i desteklemez):
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
Ahh. Yapısal tahminlerimizin şanslı olduğu anlaşılıyor. Uzun vadede, naif tahmin, 12 aylık bir ufukta ortalaması alınan en iyi tahminleri yapar (arima modeli hala en kötü modellerden biridir). 12 tahmin ufkunun her birindeki modelleri karşılaştıralım ve bunlardan herhangi birinin saf modeli geçip geçmediğini görelim:
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")
)
Açıkça, üstel yumuşatma modeli her zaman saf modeli seçmektedir (turuncu çizgi ve mavi çizgi% 100 örtüşüyor). Diğer bir deyişle, "gelecek ayın rulo fiyatlarının naif tahmini" bu ayın rulo fiyatlarıyla aynı olacak "son derece sofistike zaman serisi modellerinden 7 daha doğru (hemen hemen her tahmin ufukta). Bobin piyasasının henüz bilmediği bazı gizli bilgilere sahip olmadığınız sürece, saf bobin fiyat tahminini yenmek son derece zor olacaktır .
Asla kimsenin duymak istediği cevap değildir, ancak tahmin doğruluğu hedefinizse, en doğru modeli kullanmalısınız. Saf modeli kullanın.