Прочитав этот пост в блоге о байесовских моделях структурных временных рядов, я хотел взглянуть на реализацию этого в контексте проблемы, для которой я ранее использовал ARIMA.
У меня есть некоторые данные с некоторыми известными (но шумными) сезонными компонентами - это определенно есть ежегодные, ежемесячные и еженедельные компоненты, а также некоторые эффекты из-за особых дней (таких как федеральные или религиозные праздники).
Я использовал bsts
пакет для реализации этого и, насколько я могу судить, я не сделал ничего плохого, хотя компоненты и прогноз просто не выглядят так, как я ожидал. Мне не ясно, является ли моя реализация неправильной, неполной или имеет какую-то другую проблему.
Полный временной ряд выглядит так:
Я могу обучить модель на некотором подмножестве данных, и модель в целом выглядит хорошо с точки зрения соответствия (график ниже). Код, который я использую для этого, находится здесь:
library(bsts)
predict_length = 90
training_cut_date <- '2015-05-01'
test_cut_date <- as.Date(training_cut_date) + predict_length
df = read.csv('input.tsv', sep ='\t')
df$date <- as.Date(as.character(df$date),format="%Y-%m-%d")
df_train = df[df$date < training_cut_date,]
yts <- xts(log10(df_train$count), order.by=df_train$date)
ss <- AddLocalLinearTrend(list(), yts)
ss <- AddSeasonal(ss, yts, nseasons = 7)
ss <- AddSeasonal(ss, yts, nseasons = 12)
ss <- AddNamedHolidays(ss, named.holidays = NamedHolidays(), yts)
model <- bsts(yts, state.specification = ss, niter = 500, seed=2016)
Модель выглядит разумно:
Но если я построю прогноз, то, во-первых, тренд совершенно неправильный, а во-вторых, неопределенность растет ОЧЕНЬ быстро - до такой степени, что я не могу показать полосу неопределенности на том же графике, что и прогнозы, не делая ось y на логарифмическом масштаб. Код для этой части здесь:
burn <- SuggestBurn(0.1, model)
pred <- predict(model, horizon = predict_length, burn = burn, quantiles = c(.025, .975))
Чистый прогноз выглядит так:
И затем при уменьшении до исходного распределения (пунктирная линия показывает переход от обучения к прогнозированию, проблемы очевидны:
Я попытался добавить больше сезонных трендов, удалить сезонные тренды, добавить термин AR, изменить AddLocalLinearModel на AddGeneralizedLocalLinearTrend и ряд других вещей, касающихся настройки модели, но ничто не решило проблемы и не сделало прогнозы более значимыми. В некоторых случаях направление изменяется, поэтому вместо того, чтобы опуститься до 0, прогноз просто продолжает увеличиваться как функция времени. Я определенно не понимаю, почему модель ломается таким образом. Любые предложения будут очень приветствоваться.
Ответы:
Стив Скотт здесь. Я написал пакет BSTS. У меня есть несколько предложений для вас. Во-первых, ваши сезонные компоненты не делают то, о чем вы думаете. Я думаю, у вас есть ежедневные данные, потому что вы пытаетесь добавить 7-сезонный компонент, который должен работать правильно. Но вы сказали, что ваш ежегодный сезонный компонент повторяется каждые 12 дней. Получить ежемесячный сезонный компонент с ежедневными данными довольно сложно, но вы можете сделать это за 52 недели
AddSeasonal(..., nseasons = 52, season.duration = 7)
.seasonal.duration
Аргумент указывает модель , сколько времени указывает каждый сезон должен длиться.nseasons
Аргумент рассказывает , сколько сезонов в цикле. Общее количество временных точек в цикле равноseason.duration * nseasons
.Второе предложение заключается в том, что вы можете подумать о другой модели тренда.
LocalLinearTrend
Модель является очень гибкой, но эта гибкость может проявляться как нежелательному дисперсия долгосрочных прогнозов. Есть некоторые другие трендовые модели, которые содержат немного больше структуры.GeneralizedLocalLinearTrend
(извините за неописательное имя) предполагает, что компонент наклона тренда - это процесс AR1 вместо случайного блуждания. Это мой вариант по умолчанию, если я хочу прогнозировать далеко в будущее. Кажется, что большая часть ваших временных рядов связана с сезонностью, так что вы можете попробоватьAddLocalLevel
или дажеAddAr
вместоAddLocalLinearTrend
.Наконец, в общем, если вы получаете странные прогнозы и хотите выяснить, какая часть модели виновата, попытайтесь
plot(model, "components")
разложить модель на отдельные части, которые вы запрашивали.источник
Я думаю, что вы также можете изменить запись по умолчанию. Поскольку я использовал bsts, я создал сетку значений прожига и нитров с MAPE в качестве моей статистики за период удержания. Также попробуйте использовать AddStudentLocalLinearTrend вместо этого, если ваши данные имеют огромные отклонения, чтобы модель ожидала такого отклонения
источник