Пакет 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")
В этом методе в качестве прогноза на будущие периоды берется среднее значение ряда, вычисленное на всем историческом периоде. В данном случае не подходит, так как наблюдается явный тренд к увеличению оборота розничной торговли.
autoplot(meanf(dat1_ob, 12), series = 'Среднее ряда') +
autolayer(dat1_test, series = "Тестовый ряд") +
labs(title = "Прогноз: метод средней", x = "Год", color = NULL, y = "млрд.руб.")
Наивный прогноз - это простое повторение последнего наблюдения в качестве прогноза на будущие периоды. Выдлядит лучше метода средней, однако также не учитывает тренд.
autoplot(naive(dat1_ob, 12)) +
autolayer(dat1_test, series = "Тестовый ряд") +
labs(title = "Прогноз: наивный метод", x = "Год", color = NULL, y = "млрд.руб.")
Этот метод использует тот же принцип, что и наивный метод, однако повторяется не последнее наблюдение, а последнее наблюдение для одноименного периода. Видно, что результат практически совпадает с реальностью. Это происходит за счет учета сезонности.
autoplot(snaive(dat1_ob, 12)) +
autolayer(dat1_test, series = "Тестовый ряд") +
labs(title = "Прогноз: Сезонный наивный метод", x = "Год", color = NULL, y = "млрд.руб.")
Дрейф - это медленное изменение уровня ряда. В методе дрейфа вычисляется средний прирост уровня ряда по всем смежным периодам. Затем это значение используется для прогнозирования будущих значений. Т.е. в методе дрейфа прогнозом является продолжение прямой линии, проведенной через первое и последнее наблюдения.
autoplot(rwf(dat1_ob, 12, drift = T)) +
autolayer(dat1_test, series = "Тестовый ряд") +
labs(title = "Прогноз: Дрейф", x = "Год", color = NULL, y = "млрд.руб.")
По оценке прогнощирования можно сказать следующее:
средняя ошибка (Mean Error, ME), которая позволяет оценить систематическую ошибку (смещение) прогноза минимальна для метода дрейфа;
стандартная ошибка (Root Mean Squared Error, RMSE) - минимальна для метода сезонного наивного, однако тут разница идет менее значительная;
средняя абсолютная ошибка (Mean Absolute Error, MAE) - отличаются значительно, минимальная у метода дрейфа;
средняя абсолютная ошибка в процентах (Mean Absolute Percentage Error, MAPE) и средняя ошибка в процентах (Mean Percentage Error, MPE) - вычисляется путем усреднения относительных ошибок прогноза - минимальны так же для метода дрейфа;
Получается, что наиболее точным методом прогнощирования является метод дрейфа. Скорее всего это происходит благодаря учету сезлнности в данном методе.
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
Для агрегирования ошибок можно использовать любой общепринятый показатель. В данном случае - стандартная ошибка, 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)
Источники: