Анализ интервенций временных рядов в R

Заявление об ограничении ответственности: эта статья написана на условиях «как есть» без каких-либо гарантий. Он был написан с целью предоставить обзор концепций науки о данных и не должен интерпретироваться как совет по инвестициям или какой-либо другой профессиональный совет.

Вмешательства (или внешние факторы, не зависящие от временного ряда) часто могут влиять на указанный ряд.

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

Основная проблема при анализе вмешательств заключается в том, что невозможно проанализировать, что произошло бы, если бы вмешательство не произошло - по крайней мере, не напрямую.

Библиотека CausalImpact в R позволяет анализировать эффекты вмешательства путем использования отдельной серии (той, на которую вмешательство не влияет) в качестве ковариаты.

Наш пример

В ноябре 2017 года Банк Англии принял решение о повышении процентных ставок. Когда центральный банк страны решает манипулировать процентными ставками таким образом - это может повлиять на стоимость валюты, - учитывая, что такое решение влияет на ставку, которую инвесторы могут получить, удерживая эту конкретную валюту.

В связи с этим мы хотели бы изучить, повлияло ли повышение процентных ставок на курс фунта стерлингов / доллар США.

Для этого в качестве ковариаты выбирается валюта EUR / USD - предполагается, что эта валюта не подвержена влиянию интервенции, поскольку ЕЦБ не повышал процентные ставки в течение этого периода.

Соответствующие данные получены из базы данных FRED с помощью Quandl.

Вот график двух валют:

set.seed(1)
x1 <- eurusd$Value
y <- gbpusd$Value
data <- cbind(y, x1)
dim(data)
head(data)
matplot(data, type = "l")

При работе с финансовыми временными рядами данные обычно преобразуют в логарифмический формат. Хотя это имеет смысл, когда дело доходит до анализа цен на акции, которые имеют существенно разные шкалы цен, в этом примере данные анализируются «как есть».

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

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

pre.period <- c(1, 230)
post.period <- c(231, 249)
impact <- CausalImpact(data, pre.period, post.period)
plot(impact)

Резюме воздействия генерируется:

> summary(impact)
Posterior inference {CausalImpact}
Average           Cumulative     
Actual                   1.3               25.5           
Prediction (s.d.)        1.3 (0.0099)      25.4 (0.1878)  
95% CI                   [1.3, 1.4]        [25.1, 25.8]   
                                                          
Absolute effect (s.d.)   0.0014 (0.0099)   0.0275 (0.1878)
95% CI                   [-0.018, 0.02]    [-0.349, 0.38] 
                                                          
Relative effect (s.d.)   0.11% (0.74%)     0.11% (0.74%)  
95% CI                   [-1.4%, 1.5%]     [-1.4%, 1.5%]
Posterior tail-area probability p:   0.44186
Posterior prob. of a causal effect:  56%
For more details, type: summary(impact, "report")

Мы видим, что прогнозируемые и фактические значения (среднее) совпадают на уровне 1,3, с небольшой разницей между совокупными значениями (25,5 против 25,4).

Апостериорная вероятность причинного эффекта составляет 56%.

Рассмотрим полученный сводный отчет подробнее. В его части говорится:

Although the intervention appears to have caused a positive effect, this effect is not statistically significant when considering the entire post-intervention period as a whole. Individual days or shorter stretches within the intervention period may of course still have had a significant effect, as indicated whenever the lower limit of the impact time series (lower plot) was above zero. The apparent effect could be the result of random fluctuations that are unrelated to the intervention. This is often the case when the intervention period is very long and includes much of the time when the effect has already worn off. It can also be the case when the intervention period is too short to distinguish the signal from the noise. Finally, failing to find a significant effect can happen when there are not enough control variables or when these variables do not correlate well with the response variable during the learning period.
The probability of obtaining this effect by chance is p = 0.442. This means the effect may be spurious and would generally not be considered statistically significant.

Сравнение с pycausalimpact - версия Python

Когда тот же пример был проанализирован с помощью pycausalimpact, результаты пришли несколько иначе.

Модель была определена следующим образом:

>>> ci = CausalImpact(data, pre_period, post_period)
>>> print(ci.summary())
>>> print(ci.summary(output='report'))
>>> ci.plot()

Вот сгенерированный результат:

Posterior Inference {Causal Impact}
                          Average            Cumulative
Actual                    1.34               25.46
Prediction (s.d.)         1.32 (0.0)         25.17 (0.08)
95% CI                    [1.32, 1.33]       [25.01, 25.33]
Absolute effect (s.d.)    0.02 (0.0)         0.29 (0.08)
95% CI                    [0.01, 0.02]       [0.13, 0.45]
Relative effect (s.d.)    1.15% (0.32%)      1.15% (0.32%)
95% CI                    [0.52%, 1.77%]     [0.52%, 1.77%]
Posterior tail-area probability p: 0.0
Posterior prob. of a causal effect: 100.0%

В отличие от модели, сформулированной в R, эта модель предсказывала 100% апостериорную вероятность причинного эффекта.

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

Тем не менее, предположим, что для Priority теперь установлено значение None, то есть Prior_level_sd = None.

ci = CausalImpact(data, pre_period, post_period, prior_level_sd=None)
print(ci.summary())
print(ci.summary(output='report'))
ci.plot()

Вот результаты:

Posterior Inference {Causal Impact}
                          Average            Cumulative
Actual                    1.34               25.46
Prediction (s.d.)         1.35 (0.02)        25.57 (0.3)
95% CI                    [1.31, 1.38]       [24.98, 26.15]

Absolute effect (s.d.)    -0.01 (0.02)       -0.11 (0.3)
95% CI                    [-0.04, 0.02]      [-0.7, 0.47]

Relative effect (s.d.)    -0.45% (1.17%)     -0.45% (1.17%)
95% CI                    [-2.72%, 1.86%]    [-2.72%, 1.86%]

Posterior tail-area probability p: 0.37
Posterior prob. of a causal effect: 63.34%

Эта модель действительно предсказывает изменение курса с 1,34 до 1,35, но модель отмечает:

The probability of obtaining this effect by chance is p = 36.66%.
This means the effect may be spurious and would generally not be
considered statistically significant.

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

Вывод

В этой статье вы увидели:

  • Использование CausalImpact в R для прогнозирования вмешательств
  • Чем версии R и Python отличаются друг от друга
  • Роль предварительных допущений в определении обнаружения вмешательств
  • Анализ вмешательства и генерация сводных отчетов

Большое спасибо за чтение, любые вопросы или отзывы приветствуются.

использованная литература