Представьте, что вы управляете онлайн-бизнесом, таким как Amazon.com, и хотите запланировать ресурсы сервера на следующий год - вам обязательно нужно знать, когда ваша нагрузка вырастет (или, по крайней мере, когда она увеличилась в ретроспективе, чтобы поверить он будет повторяться снова), и именно здесь обнаружение аномалий временных рядов - это то, что вам нужно. Хотя есть некоторые пакеты, такие как AnomalyDetection Твиттера, которые выполняют эту работу, есть еще один хороший кандидат - anomalize - который делает что-то особенное, чего не делали никакие другие пакеты обнаружения аномалий. Это Tidy Anomaly Detection.

Обратите внимание: цель этой статьи - помочь вам выполнить обнаружение аномалий в R - The Tidy Way, а не научить вас принципам и концепциям обнаружения аномалий или данных временных рядов.

Что означает обнаружение аномалий с помощью R - The Tidy Way?

Мне очень жаль это говорить! Специалисты по данным, использующие R, как известно, пишут неуклюжий код - код, который не очень читается, и код, который не очень эффективен, но эта тенденция меняется из-за принципа tidy, популяризированного Хэдли Уикхэмом, который якобы не нуждается в представлении. во вселенной R, потому что его tidyverse - это то, что способствует эффективности и работе многих ученых R Data. Теперь этот новый пакет anomalize с открытым исходным кодом от Business Science выполняет обнаружение аномалий временных рядов, которое совпадает с другими пакетами Tidyverse (или пакетами, поддерживающими аккуратные данные) - с одной из наиболее часто используемых функций Tidyverse - совместимостью с оператором pipe %>% для записывать читаемый и воспроизводимый конвейер данных.

anomalize - Установка

Стабильная версия аномалии пакета R доступна на CRAN, которую можно установить, как показано ниже:

install.packages('anomalize')

Последняя разрабатываемая версия anomalize доступна на github, которую можно установить, как показано ниже:

#install.packages('devtools') 
devtools::install_github("business-science/anomalize")

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

Кейс - Обнаружение аномалий цены биткойнов

Легче выучить новую концепцию или фрагмент кода, фактически выполняя и соотнося их с тем, чем мы являемся. Итак, чтобы понять Tidy Anomaly Detection в R, мы попытаемся обнаружить аномалии в цене биткойнов с 2017 года.

Загрузка необходимых пакетов

Мы используем следующие 3 пакета для решения вышеуказанного случая:

library(anomalize) #tidy anomaly detectiom
library(tidyverse) #tidyverse packages like dplyr, ggplot, tidyr
library(coindeskr) #bitcoin price extraction from coindesk

Извлечение данных

Мы используем get_historic_price() из coindeskr для извлечения исторической цены биткойнов из Coindesk. Результирующий фрейм данных сохраняется в объекте btc.

btc <- get_historic_price(start = "2017-01-01")

Предварительная обработка данных

Для обнаружения аномалий с использованием anomalize нам нужен объект tibble или tibbletime. Следовательно, мы должны преобразовать фрейм данных btc в тибл-объект, который следует форме временного ряда, и сохранить его в btc_ts.

btc_ts <- btc %>% rownames_to_column() %>% as.tibble() %>% 
  mutate(date = as.Date(rowname)) %>% select(-one_of('rowname'))

Просто посмотрите на заголовок btc_ts, чтобы увидеть образцы данных:

head(btc_ts)
 Price date      
1  998. 2017-01-01
2 1018. 2017-01-02
3 1031. 2017-01-03
4 1130. 2017-01-04
5 1006. 2017-01-05
6  896. 2017-01-06

Разложение временных рядов с аномалиями

Одна из важных вещей, которую нужно сделать с данными временных рядов перед тем, как начать прогнозирование или моделирование временных рядов, - это декомпозиция временных рядов, при которой данные временных рядов разлагаются на компоненты «Сезонный», «Тренд» и «Остаток». У anomalize есть функция time_decompose(), которая выполняет то же самое. После того, как компоненты разложены, anomalize может обнаруживать и отмечать аномалии в разложенных данных компонента напоминания, которые затем могут быть визуализированы с помощью plot_anomaly_decomposition() .

btc_ts %>% 
  time_decompose(Price, method = "stl", frequency = "auto", trend = "auto") %>%
  anomalize(remainder, method = "gesd", alpha = 0.05, max_anoms = 0.2) %>%
  plot_anomaly_decomposition()

Дает этот сюжет:

Как видно из приведенного выше кода, декомпозиция происходит на основе метода stl, который является распространенным методом декомпозиции временных рядов, но если вы использовали Twitter AnomalyDetection, то то же самое можно реализовать в anomalize, объединив time_decompose (method = «Twitter») с anomalize(method = "gesd"). Кроме того, метод декомпозиции «stl» также может быть объединен с anomalize(method = "iqr") для обнаружения различных аномалий на основе IQR.

Обнаружение аномалий

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

btc_ts %>% 
  time_decompose(Price) %>%
  anomalize(remainder) %>%
  time_recompose() %>%
  plot_anomalies(time_recomposed = TRUE, ncol = 3, alpha_dots = 0.5)

Дает этот сюжет:

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

Если вы заинтересованы в извлечении фактических точек данных, которые являются аномалиями, можно использовать следующий код:

btc_ts %>% 
  time_decompose(Price) %>%
  anomalize(remainder) %>%
  time_recompose() %>%
  filter(anomaly == 'Yes') 
Converting from tbl_df to tbl_time.
Auto-index message: index = date
frequency = 7 days
trend = 90.5 days
# A time tibble: 58 x 10
# Index: date
   date       observed   season trend remainder remainder_l1 remainder_l2 anomaly recomposed_l1
                                                 
 1 2017-11-12    5857.  36.0    7599.    -1778.       -1551.        1672. Yes             6085.
 2 2017-12-04   11617.  11.2    9690.     1916.       -1551.        1672. Yes             8150.
 3 2017-12-05   11696.  -2.01   9790.     1908.       -1551.        1672. Yes             8237.
 4 2017-12-06   13709.  -9.11   9890.     3828.       -1551.        1672. Yes             8330.
 5 2017-12-07   16858.   0.0509 9990.     6868.       -1551.        1672. Yes             8439.
 6 2017-12-08   16057. -28.1    9971.     6114.       -1551.        1672. Yes             8393.
 7 2017-12-09   14913.  -8.03   9953.     4969.       -1551.        1672. Yes             8394.
 8 2017-12-10   15037.  36.0    9934.     5067.       -1551.        1672. Yes             8420.
 9 2017-12-11   16700.  11.2    9916.     6773.       -1551.        1672. Yes             8376.
10 2017-12-12   17178.  -2.01   9897.     7283.       -1551.        1672. Yes             8345.
# ... with 48 more rows, and 1 more variable: recomposed_l2

Таким образом, anomalize упрощает обнаружение аномалий в R с помощью более чистого кода, который также можно использовать в любом конвейере данных, созданном с использованием tidyverse. Используемый здесь код доступен на моем гитхабе. Если вы хотите узнать больше о прогнозировании временных рядов в R, ознакомьтесь с курсом профессора Роба Хайндмана по Datacamp.