Загрузка данных

Пакет sophisthse предназначен для скачивания временных рядов с sophist.hse.ru.

Загрузка нужного ряда данных и его описание:

dat <- sophisthse("RTRD_M_I")
sophisthse_metadata(dat)
## # A tibble: 3 x 7
##   tsname  unit   fullname     methodology     source     comment      freq
##   <chr>   <chr>  <chr>        <chr>           <chr>      <chr>       <dbl>
## 1 RTRD_M… 1994.… Индекс реал… Индекс физичес… Федеральн… Пересчет и…    12
## 2 RTRD_M… 1994.… Индекс реал… Сезонное сглаж… Рассчитан… -              12
## 3 RTRD_M  млрд.… Оборот розн… Оборот розничн… Федеральн… -              12

Получили таблицу, в которой присутствует три ряда: Индекс реального оборота розничной торговли (RTRD_M_DIRI), Индекс реального оборота розничной торговли, с поправкой на сезонность (RTRD_M_DIRI_SA), Оборот розничной торговли в текущих ценах (RTRD_M).

Извлекаем один:

dat1 <- dat[, 'RTRD_M'] # извлекаем 3-й столбец
dat1 <- window(dat1, start = 1995) # исключаем пропущенные значения

dygraph(dat1, main = "Оборот розничной торговли в текущих ценах",
        xlab = "Год", 
        ylab = "млрд.руб.") %>%
  dyLegend(show = "follow") %>%
  dyRangeSelector()

Разделение ряда

Цель данной работы - выбрать наиболее подходящую модель прогноза. Для этого произведем разделение данных на обучающие и тестовые.

dat1_ob <- window(dat1, end = c(2017, 10))
dat1_test <- window(dat1, start = c(2017,10))

dygraph(cbind(dat1_ob, dat1_test), main = "Оборот розничной торговли в текущих ценах") %>%
  dySeries("dat1_ob", label = "Обучающие") %>%
  dySeries("dat1_test", label = "Тестовые") %>%
  dyRangeSelector() %>%
  dyLegend(show = "follow")

Прогноз

Метод усреднения (Average Method)

В этом методе в качестве прогноза на будущие периоды берется среднее значение ряда, вычисленное на всем историческом периоде. В данном случае не подходит, так как наблюдается явный тренд к увеличению оборота розничной торговли.

autoplot(meanf(dat1_ob, 12), series = 'Среднее ряда') +
  autolayer(dat1_test, series = "Тестовый ряд") +
  labs(title = "Прогноз: метод средней", x = "Год", color = NULL, y = "млрд.руб.")

Наивный метод (Naïve method)

Наивный прогноз - это простое повторение последнего наблюдения в качестве прогноза на будущие периоды. Выдлядит лучше метода средней, однако также не учитывает тренд.

autoplot(naive(dat1_ob, 12)) +
  autolayer(dat1_test, series = "Тестовый ряд") +
  labs(title = "Прогноз: наивный метод", x = "Год", color = NULL, y = "млрд.руб.")

Сезонный наивный метод (Seasonal naïve method)

Этот метод использует тот же принцип, что и наивный метод, однако повторяется не последнее наблюдение, а последнее наблюдение для одноименного периода. Видно, что результат практически совпадает с реальностью. Это происходит за счет учета сезонности.

autoplot(snaive(dat1_ob, 12)) +
  autolayer(dat1_test, series = "Тестовый ряд") +
  labs(title = "Прогноз: Сезонный наивный метод", x = "Год", color = NULL, y = "млрд.руб.")

Метод дрейфа (Drift Method)

Дрейф - это медленное изменение уровня ряда. В методе дрейфа вычисляется средний прирост уровня ряда по всем смежным периодам. Затем это значение используется для прогнозирования будущих значений. Т.е. в методе дрейфа прогнозом является продолжение прямой линии, проведенной через первое и последнее наблюдения.

autoplot(rwf(dat1_ob, 12, drift = T)) +
  autolayer(dat1_test, series = "Тестовый ряд") +
  labs(title = "Прогноз: Дрейф", x = "Год", color = NULL, y = "млрд.руб.")

Оценка точности прогнозирования

По оценке прогнощирования можно сказать следующее:

Получается, что наиболее точным методом прогнощирования является метод дрейфа. Скорее всего это происходит благодаря учету сезлнности в данном методе.

rbind(accuracy(naive(dat1_ob, 12)),
      accuracy(snaive(dat1_ob, 12)),
      accuracy(rwf(dat1_ob, 12, drift = T))) %>%
  as_tibble() %>%
  round(2) %>%
  mutate(`Метод` = c('Наивный', 'С. наивный', 'Дрейф')) %>%
  select(`Метод`, everything()) %>%
  arrange(MASE)
## # A tibble: 3 x 8
##   Метод         ME  RMSE   MAE    MPE  MAPE  MASE  ACF1
##   <chr>      <dbl> <dbl> <dbl>  <dbl> <dbl> <dbl> <dbl>
## 1 Дрейф        0    142.  58.2  -2.89  7.07  0.52 -0.41
## 2 Наивный      9.4  143.  60.0   1.22  5.86  0.54 -0.41
## 3 С. наивный 111.   135. 111.   16.4  16.4   1     0.92

Метод скользящего контроля (cross-validation)

Для агрегирования ошибок можно использовать любой общепринятый показатель. В данном случае - стандартная ошибка, RMSE. Для удобства, создадим функцию, вычисляющую этот показатель.

С течением времени (увеличения горизонта планирования) наиблюдается увеличение стандартной ошибки. Выбранная модель не идеальна.

RMSE <- function(errors) {
  errors^2 %>% mean(na.rm = T) %>% sqrt()
}

# Исследуем, как зависит стандартная ошибка прогноза от горизонта прогнозирования.
b <- tibble(horizon = 1:12) %>%
  mutate(error = map_dbl(horizon, 
                         function(x) tsCV(dat1_ob, rwf, h = x) %>% RMSE()))

ggplot(b, aes(horizon, error)) +
  geom_line() +
  labs(title = 'RMSE прогноза оборота розничной торговли',
       x = 'h', y = "млрд.руб.") +
  scale_x_continuous(breaks = b$horizon)


Источники: