Bạn nên sử dụng gói dự báo , hỗ trợ tất cả các mô hình này (và hơn thế nữa) và làm cho chúng phù hợp nhanh chóng:
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)
Tôi sẽ khuyên không nên làm mịn dữ liệu trước khi lắp mô hình của bạn. Mô hình của bạn vốn đã cố gắng làm mịn dữ liệu, vì vậy việc làm mịn trước chỉ làm phức tạp mọi thứ.
Chỉnh sửa dựa trên dữ liệu mới:
Nó thực sự trông giống như arima là một trong những mô hình tồi tệ nhất bạn có thể chọn cho tập huấn luyện và thử nghiệm này.
Tôi đã lưu dữ liệu của bạn vào một cuộc gọi tệp coil.csv
, tải nó vào R và chia nó thành tập huấn luyện và kiểm tra:
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))
Tiếp theo tôi phù hợp với một loạt các mô hình chuỗi thời gian: arima, làm mịn theo cấp số nhân, mạng lưới thần kinh, tbats, dơi, phân rã theo mùa và chuỗi thời gian cấu trúc:
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)
)
Sau đó, tôi đã thực hiện một số dự báo và so sánh với bộ thử nghiệm. Tôi đã bao gồm một dự báo ngây thơ luôn dự đoán một đường thẳng, ngang:
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')
}
Như bạn có thể thấy, mô hình arima có xu hướng sai, nhưng tôi giống như kiểu của "Mô hình kết cấu cơ bản"
Cuối cùng, tôi đã đo độ chính xác của từng mô hình trên bộ thử nghiệ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
Các số liệu được sử dụng được mô tả trong Hyndman, RJ và Athanasopoulos, G. (2014) "Dự báo: nguyên tắc và thực hành" , người cũng tình cờ là tác giả của gói dự báo. Tôi đặc biệt khuyên bạn nên đọc văn bản của họ: nó có sẵn miễn phí trên mạng. Chuỗi thời gian cấu trúc là mô hình tốt nhất theo một số số liệu, bao gồm MASE, đây là số liệu tôi có xu hướng thích lựa chọn mô hình.
Một câu hỏi cuối cùng là: mô hình cấu trúc có gặp may mắn trong bộ thử nghiệm này không? Một cách để đánh giá điều này là xem xét các lỗi tập huấn luyện. Lỗi tập huấn luyện ít đáng tin cậy hơn lỗi tập kiểm thử (vì chúng có thể quá khớp), nhưng trong trường hợp này, mô hình cấu trúc vẫn xuất hiện trên đầu:
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
(Lưu ý rằng mạng nơ-ron hoạt động quá mức, hoạt động xuất sắc trên tập huấn luyện và kém trên tập kiểm tra)
Cuối cùng, sẽ là một ý tưởng tốt để xác nhận chéo tất cả các mô hình này, có thể bằng cách đào tạo vào năm 2008-2009 / thử nghiệm vào năm 2010, đào tạo vào năm 2008-2010 / thử nghiệm vào năm 2011, đào tạo vào năm 2008-2011 / thử nghiệm vào năm 2012, đào tạo vào năm 2012 vào 2008-2012 / thử nghiệm vào năm 2013 và tính trung bình các lỗi trong tất cả các khoảng thời gian này. Nếu bạn muốn đi theo tuyến đường đó, tôi có gói hoàn chỉnh một phần cho các mô hình chuỗi thời gian xác thực chéo trên github mà tôi muốn bạn dùng thử và gửi cho tôi yêu cầu phản hồi / kéo về:
devtools::install_github('zachmayer/cv.ts')
library(cv.ts)
Chỉnh sửa 2: Hãy xem tôi có nhớ cách sử dụng gói của riêng mình không!
Trước hết, cài đặt và tải gói từ github (xem bên trên). Sau đó xác thực chéo một số mô hình (sử dụng bộ dữ liệu đầy đủ):
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)
(Lưu ý rằng tôi đã giảm tính linh hoạt của mô hình mạng thần kinh, để cố gắng ngăn chặn nó quá mức)
Khi chúng tôi phù hợp với các mô hình, chúng tôi có thể so sánh chúng bằng MAPE (cv.ts chưa hỗ trợ 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
Ôi. Nó sẽ xuất hiện rằng dự báo cấu trúc của chúng tôi đã gặp may mắn. Về lâu dài, dự báo ngây thơ đưa ra dự báo tốt nhất, tính trung bình trên đường chân trời 12 tháng (mô hình arima vẫn là một trong những mô hình tồi tệ nhất). Chúng ta hãy so sánh các mô hình ở mỗi trong số 12 chân trời dự báo và xem liệu có ai trong số họ từng đánh bại mô hình ngây thơ không:
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")
)
Nói một cách dễ hiểu, mô hình làm mịn theo cấp số nhân luôn chọn mô hình ngây thơ (đường màu cam và đường màu xanh trùng nhau 100%). Nói cách khác, dự báo ngây thơ về "giá cuộn dây của tháng tới sẽ giống như giá cuộn dây của tháng này" chính xác hơn (ở hầu hết mọi chân trời dự báo) so với 7 mô hình chuỗi thời gian cực kỳ tinh vi. Trừ khi bạn có một số thông tin bí mật mà thị trường cuộn dây chưa biết, việc đánh bại dự báo giá cuộn dây ngây thơ sẽ vô cùng khó khăn .
Đó không bao giờ là câu trả lời mà bất cứ ai muốn nghe, nhưng nếu dự đoán độ chính xác là mục tiêu của bạn, bạn nên sử dụng mô hình chính xác nhất. Sử dụng mô hình ngây thơ.