Применение декомпозиции временных рядов (и обнаружение аномалий) над скользящим / плиточным окном - PullRequest
0 голосов
/ 21 мая 2019

Методы обнаружения аномалий, опубликованные и оставленные twitter , раздельно обрабатывались и поддерживаются в пакете anomalize и вилке hrbrmstr/AnomalyDetection . Оба реализовали «аккуратные» функции.

Рабочие статические версии

tidyverse_cran_downloads %>% 
  filter(package == "tidyr") %>% 
  ungroup() %>% 
  select(-package) -> one_package_only

one_package_only %>% 
  anomalize::time_decompose(count,
                 merge = TRUE,
                 method = "twitter",
                 frequency = "7 days") -> one_package_only_decomp

one_package_only_decomp %>%
  anomalize::anomalize(remainder, method = "iqr") %>%
  anomalize::time_recompose()


one_package_only_decomp %>% 
  select(date, remainder) %>%
  AnomalyDetection::ad_ts(max_anoms = 0.02,
        direction = 'both')

Они работают как положено.

Я хотел бы применить процесс обнаружения аномалий в твиттере к плиточному окну к моему набору данных, который по структуре похож на набор данных anomalize::tidyverse_cran_downloads. Обычный набор из более чем 100 наблюдений значения, сгруппированных по категориальному определению.

В пакете tsibble (который заменяет старый tibbletime) есть метод применения функции в purrr -подобном синтаксисе через slide, tile и stretch . Это может включать в себя возврат полного объекта, подобного фрейму данных, внутри другого объекта, подобного фрейму данных, согласно purrr. (Что за предложение!)

Я прошел через виньетку оконной функции 1030 *, но мне не повезло.

Попытка 1 slide2:

Функция anomalize::decompose_twitter принимает два аргумента, data и target

tidyverse_cran_downloads %>%
  mutate(
    Monthly_MA = slide2_dfr(
      .x = .,
      .y = count,
      ~ anomalize::decompose_twitter,
      .size = 5
    )
  )

Error: Element 1 has length 3, not 1 or 425. Call rlang :: LAST_ERROR () to see a backtrace

Может быть, я неправильно понял, как работает синтаксис .x .y?

Попытка 2: pmap

my_diag <- function(...) {
  data <- tibble(...)
  fit <- anomalize::decompose_twitter(data = data, target = count)
}

tidyverse_cran_downloads %>%
  nest(-package) %>%
  filter(package %in% c("tidyr", "lubridate")) %>%  # just to make it quick
  mutate(diag = purrr::map(data, ~ pslide_dfr(., my_diag, .size = 7)))

Error in stats::stl(., s.window = "periodic", robust = TRUE) : series is not periodic or has less than two periods

Появляется, что что-то запущено, но период между наблюдениями как-то выключен или не анализируется?

Попытка 3: ad_ts

ad_ts принимает только один аргумент, поэтому, игнорируя тот факт, что нам еще предстоит найти способ вычисления остатка после декомпозиции, я смог бы использовать его через slide. Также ожидается, что x будет:

Временной ряд в виде фрейма данных из двух столбцов, в котором первый столбец состоит из меток времени, а второй столбец - из наблюдений.

Так что нам не нужно много делать с данными после их вложения.

tidyverse_cran_downloads %>%
  nest(-package, .key = "my_data") %>%
  mutate(
    Daily_MA = slide_dfr(
      .f = AnomalyDetection::ad_ts,
      .x = my_data
    )
  )

Error in .f(.x[[i]], ...) : data must be a single data frame.

То есть функция по крайней мере вызывается, но вызывается более чем одним фреймом данных?

Я хочу:

  • Применение процесса декомпозиции по алгоритму Твиттера с последующим обнаружением аномалий в оставшейся части
  • Для этого используйте один из двух пакетов обнаружения аномалий или сочетание двух
  • Примените его к окну времени
  • Сгруппированные категориальные данные

Единственное отличие моего набора данных заключается в том, что у меня есть получасовые наблюдения значений за период в течение нескольких месяцев , и мне фактически нужны только пересчеты аномалий каждый день (т.е. один раз каждые 48 наблюдений), где окно оглядывается на предыдущие 30 дней , чтобы разложить и обнаружить их.

(N.B. Я бы пометил tsibble и anomalize, но у меня нет представителя, чтобы сделать эти теги)

1 Ответ

2 голосов
/ 22 мая 2019

Подход 2 должен работать как положено? Сообщение об ошибке относится к stl(), для оценки которого требуется как минимум два сезонных периода. Например, для выполнения ежедневных данных требуется * 14 наблюдений stl(). Увеличение размера окна .size = 7 * 3 отлично работает.

my_decomp <- function(...) {
  data <- tibble(...)
  anomalize::decompose_twitter(data, count)
}

library(dplyr)
library(anomalize)
tidyverse_cran_downloads %>%
  group_by(package) %>% 
  tidyr::nest() %>% 
  mutate(diag = purrr::map(data, ~ tsibble::pslide_dfr(., my_decomp, .size = 7 * 3)))
#> # A tibble: 15 x 3
#>    package   data               diag                
#>    <chr>     <list>             <list>              
#>  1 tidyr     <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  2 lubridate <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  3 dplyr     <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  4 broom     <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  5 tidyquant <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  6 tidytext  <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  7 ggplot2   <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  8 purrr     <tibble [425 × 2]> <tibble [8,506 × 5]>
#>  9 glue      <tibble [425 × 2]> <tibble [8,506 × 5]>
#> 10 stringr   <tibble [425 × 2]> <tibble [8,506 × 5]>
#> 11 forcats   <tibble [425 × 2]> <tibble [8,506 × 5]>
#> 12 knitr     <tibble [425 × 2]> <tibble [8,506 × 5]>
#> 13 readr     <tibble [425 × 2]> <tibble [8,506 × 5]>
#> 14 tibble    <tibble [425 × 2]> <tibble [8,506 × 5]>
#> 15 tidyverse <tibble [425 × 2]> <tibble [8,506 × 5]>
...