R语言时间序列分解和异常检测方法应用案例

原文链接:http://tecdat.cn/?p=3232

我们最近有一个很棒的机会与一位客户合作,要求构建一个适合他们需求的异常检测算法。业务目标是准确地检测各种营销数据的异常情况,这些数据包括跨多个客户和Web源数千个时间序列的网站操作和营销反馈。异常检测算法,该算法基于时间并可从一个到多个时间序列进行扩展。

案例研究

我们与许多教授数据科学的客户合作,并利用我们的专业知识加速业务发展。

我们的客户遇到了一个具有挑战性的问题:按时间顺序检测每日或每周数据的时间序列异常。异常表示异常事件,可能是营销域中的Web流量增加或IT域中的故障服务器。无论如何,标记这些不寻常的事件确保业务顺利运行非常重要。其中一个挑战是客户处理的不是一个时间序列,而是需要针对这些极端事件进行分析。

anomalize

这里有四个简单步骤的工作要点。

第1步:安装

install.packages("tidyverse")

第2步:加载

library(tidyverse)

第3步:收集时间序列数据

tidyverse\_cran\_downloads

## # A tibble: 6,375 x 3

## # Groups: package \[15\]

## date count package

##

## 1 2017-01-01 873. tidyr

## 2 2017-01-02 1840. tidyr

## 3 2017-01-03 2495. tidyr

## 4 2017-01-04 2906. tidyr

## 5 2017-01-05 2847. tidyr

## 6 2017-01-06 2756. tidyr

## 7 2017-01-07 1439. tidyr

## 8 2017-01-08 1556. tidyr

## 9 2017-01-09 3678. tidyr

## 10 2017-01-10 7086. tidyr

## # ... with 6,365 more rows

第4步:异常化

使用功能及时发现异常情况。

异常检测工作流程

其中包括:

  • 用时间序列分解

  • 用检测异常

  • 异常下限和上限转换

时间序列分解

第一步是使用时间序列分解。“计数”列被分解为“观察”,“季节”,“趋势”和“剩余”列。时间序列分解的默认值是method = "stl",使用平滑器进行季节性分解。

## # A time tibble: 6,375 x 6

## # Index: date

## # Groups: package \[15\]

## package date observed season trend remainder

##

## 1 tidyr 2017-01-01 873. -2761. 5053. -1418.

## 2 tidyr 2017-01-02 1840. 901. 5047. -4108.

## 3 tidyr 2017-01-03 2495. 1460. 5041. -4006.

## 4 tidyr 2017-01-04 2906. 1430. 5035. -3559.

## 5 tidyr 2017-01-05 2847. 1239. 5029. -3421.

## 6 tidyr 2017-01-06 2756. 367. 5024. -2635.

## 7 tidyr 2017-01-07 1439. -2635. 5018. -944.

## 8 tidyr 2017-01-08 1556. -2761. 5012. -695.

## 9 tidyr 2017-01-09 3678. 901. 5006. -2229.

## 10 tidyr 2017-01-10 7086. 1460. 5000. 626.

## # ... with 6,365 more rows

frequency并trend自动为您选择。此外,可以通过输入基于时间的周期(例如“1周”或“2个季度”)来更改选择,可以确定有多少观察属于时间跨度。

异常检测

下一步是对分解的数据执行异常检测。产生了三个新列:“remainder\_l1”(下限),“remainder\_l2”(上限)和“异常”(是/否标志)。默认方法是method = "iqr",在检测异常时快速且相对准确。

## # Groups: package \[15\]

## package date observed season trend remainder remainder_l1

##

## 1 tidyr 2017-01-01 873. -2761. 5053. -1418. -3748.

## 2 tidyr 2017-01-02 1840. 901. 5047. -4108. -3748.

## 3 tidyr 2017-01-03 2495. 1460. 5041. -4006. -3748.

## 4 tidyr 2017-01-04 2906. 1430. 5035. -3559. -3748.

## 5 tidyr 2017-01-05 2847. 1239. 5029. -3421. -3748.

## 6 tidyr 2017-01-06 2756. 367. 5024. -2635. -3748.

## 7 tidyr 2017-01-07 1439. -2635. 5018. -944. -3748.

## 8 tidyr 2017-01-08 1556. -2761. 5012. -695. -3748.

## 9 tidyr 2017-01-09 3678. 901. 5006. -2229. -3748.

## 10 tidyr 2017-01-10 7086. 1460. 5000. 626. -3748.

## # ... with 6,365 more rows, and 2 more variables: remainder_l2 ,

## # anomaly

现在尝试另一个绘图功能。它只适用于单个时间序列。“季节”消除每周的季节性。趋势是平滑的。最后,检测最重要的异常值。

tidyverse\_cran\_downloads %>%

time_decompose(count, method = "stl", frequency = "auto", trend = "auto") %>%

anomalize(remainder, method = "iqr", alpha = 0.05, max_anoms = 0.2) %>%

plot\_anomaly\_decomposition() +

异常下限和上限

最后一步是围绕“观察”值创建下限和上限。创建了两个新列:“recomposed\_l1”(下限)和“recomposed\_l2”(上限)。

## # A time tibble: 6,375 x 11

## # Index: date

## # Groups: package \[15\]

## package date observed season trend remainder remainder_l1

##

## 1 tidyr 2017-01-01 873. -2761. 5053. -1418. -3748.

## 2 tidyr 2017-01-02 1840. 901. 5047. -4108. -3748.

## 3 tidyr 2017-01-03 2495. 1460. 5041. -4006. -3748.

## 4 tidyr 2017-01-04 2906. 1430. 5035. -3559. -3748.

## 5 tidyr 2017-01-05 2847. 1239. 5029. -3421. -3748.

## 6 tidyr 2017-01-06 2756. 367. 5024. -2635. -3748.

## 7 tidyr 2017-01-07 1439. -2635. 5018. -944. -3748.

## 8 tidyr 2017-01-08 1556. -2761. 5012. -695. -3748.

## 9 tidyr 2017-01-09 3678. 901. 5006. -2229. -3748.

## 10 tidyr 2017-01-10 7086. 1460. 5000. 626. -3748.

## # ... with 6,365 more rows, and 4 more variables: remainder_l2 ,

## # anomaly , recomposed\_l1 , recomposed\_l2

让我们看一下“lubridate”数据。我们可以plot\_anomalies()和设置time\_recomposed = TRUE。此功能适用于单个和分组数据。

time_decompose(count, method = "stl", frequency = "auto", trend = "auto") %>%

anomalize(remainder, method = "iqr", alpha = 0.05, max_anoms = 0.2) %>%

time_recompose() %>%

# 绘制异常分解

plot\_anomalies(time\_recomposed = TRUE) +

ggtitle("Lubridate Downloads: Anomalies Detected")

预测

forecast是在执行预测之前有效收集异常值的好方法。它使用基于STL的离群值检测方法。它非常快,因为最多有两次迭代来确定异常值带。

结论

R软件非常有效地用于检测异常的许多传统预测时间序列。但是,速度是一个问题,特别是在尝试扩展到多个时间序列时。

我们从中了解到所有软件包的最佳组合:

  • 分解方法:我们包括两个时间序列分解方法:( "stl"使用Loess的传统季节分解)和"twitter"(使用中间跨度的季节分解)。

  • 异常检测方法:我们包括两种异常检测方法:( "iqr"使用类似于3X IQR的方法forecast::tsoutliers())和"gesd"(使用Twitter使用的GESD方法AnomalyDetection)。

有问题欢迎下方留言!

(0)

相关推荐