Предсказания от модели BSTS (в R) полностью проваливаются

15

Прочитав этот пост в блоге о байесовских моделях структурных временных рядов, я хотел взглянуть на реализацию этого в контексте проблемы, для которой я ранее использовал 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, прогноз просто продолжает увеличиваться как функция времени. Я определенно не понимаю, почему модель ломается таким образом. Любые предложения будут очень приветствоваться.

anthr
источник
2
Почему бы вам не опубликовать свои данные, и я постараюсь помочь ... Я не смогу ответить, почему модель выходит из строя, поскольку я не использую этот подход, поскольку в нем заложено слишком много предположений. точное количество удержанных ценностей, дата начала и страна происхождения.
IrishStat
Большое спасибо за ваш комментарий. Я загрузил исходные данные здесь в случае , если у вас есть время , чтобы посмотреть. Данные варьируются с начала 2013 года до конца этого года. Я также пытался прогнозировать с помощью модели ARIMA, но прогнозы из этого также не соответствовали данным об удержании. Данные удержания составляют в основном лишь некоторую долю 2015 или 2016 года, в зависимости от того, сколько данных об обучении я хотел использовать.
Anthr
У меня проблема с загрузкой .. отправьте CSV-файл на мой адрес электронной почты
IrishStat

Ответы:

26

Стив Скотт здесь. Я написал пакет 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")разложить модель на отдельные части, которые вы запрашивали.

Стив Скотт
источник
К вашему сведению: у меня очень похожие проблемы с моими данными, что также ежедневно. Я реализовал все ваши предложения, перечисленные здесь, и ни одно из них не помогло.
ZakJ
1
@ Стив Скотт Извините, что беспокою вас, Стив, я хочу спросить вас: если я пытаюсь смоделировать несколько временных рядов и нахожусь в иерархической структуре смешанной модели, могу ли я смоделировать это с помощью вашего пакета? Кстати: большое спасибо за ваш пакет!
Томмазо
4

Я думаю, что вы также можете изменить запись по умолчанию. Поскольку я использовал bsts, я создал сетку значений прожига и нитров с MAPE в качестве моей статистики за период удержания. Также попробуйте использовать AddStudentLocalLinearTrend вместо этого, если ваши данные имеют огромные отклонения, чтобы модель ожидала такого отклонения

Elderkm2012
источник
1
Был полезен в моем случае, когда у меня было мало точек данных (20)
SCallan