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


2
Чому б ти не опублікував свої дані, і я спробую допомогти ... Я не зможу відповісти, чому модель руйнується, оскільки я не використовую цей підхід, оскільки в неї закладено занадто багато припущень. Будь ласка, будьте точно, скільки затриманих цінностей, дата початку та країна походження.
IrishStat

Дуже дякую за ваш коментар. Я завантажив сюди необроблені дані на випадок, якщо ви встигнете поглянути. Дані коливаються від початку 2013 року до кінця цього року. Я також намагався прогнозувати за допомогою моделі ARIMA, але прогнози з цього не відповідали даним про затримку. Дані про витримки - це лише певна частка 2015 або 2016 років, залежно від того, скільки даних тренувань я хотів використати.
anthr

У мене
виникають

Відповіді:


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")побачити модель, розкладену на окремі деталі, про які ви просили.


FYI: У мене дуже схожі проблеми зі своїми даними, які також є щоденними. Я реалізував усі ваші запропоновані тут пропозиції, і жодна, здається, не допоможе.
ZakJ

1
@Steve Scott Вибачте за те, що турбував вас Стів, я хочу вас запитати так: Якщо я намагаюся моделювати кілька часових рядів і я перебуваю в ієрархічній змішаній моделі, чи можу я моделювати це за допомогою вашого пакета? До речі: дуже дякую за пакет!
Томмазо Герріні

4

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


1
Був корисний у моєму випадку, коли у мене було декілька точок даних (20)
SCallan
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.