咱們最近有一個很棒的機會與一位偉大的客戶合做,要求Business Science構建一個適合他們需求的開源異常檢測算法。業務目標是準確地檢測各類營銷數據的異常狀況,這些數據包括跨多個客戶和Web源跨越數千個時間序列的網站操做和營銷反饋。輸入anomalize:一個整潔的異常檢測算法,該算法基於時間(創建在之上tibbletime)並可從一個到多個時間序列進行擴展!咱們很是高興可以爲其餘人提供這個開源R軟件包以使其受益。在這篇文章中,咱們將概述anomalize它的做用和方式。算法
咱們與許多教授數據科學的客戶合做,並利用咱們的專業知識加速業務發展。然而,不多有客戶的需求和他們願意讓其餘人受益於咱們推進數據科學界限的利益。這是一個例外。服務器
咱們的客戶遇到了一個具備挑戰性的問題:按時間順序檢測每日或每週數據的時間序列異常。異常表示異常事件,多是營銷域中的Web流量增長或IT域中的故障服務器。不管如何,標記這些不尋常的事件以確保業務順利運行很是重要。其中一個挑戰是客戶處理的不是一個時間序列,而是須要針對這些極端事件進行分析。函數
咱們有機會開發一個開源軟件包,該軟件包符合咱們的興趣,即構建Twitter AnomalyDetection軟件包的可擴展版本,以及咱們的客戶但願得到一個能夠從開源數據科學社區隨着時間的推移而改進的軟件包的願望。結果是anomalize!!!網站
對於咱們這些喜歡閱讀的人來講,這裏有anomalize四個簡單步驟的工做要點。spa
第1步:安裝Anomalize install.packages("anomalize") 第2步:加載Tidyverse和Anomalize library(tidyverse) library(anomalize) 第3步:收集時間序列數據 咱們提供了一個數據集,tidyverse_cran_downloads以幫助您啓動和運行。該數據集包括15「tidyverse」包的每日下載次數。 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步:異常化 使用三個整齊的功能:time_decompose(),anomalize(),並time_recompose()及時發現異常狀況。
您剛剛實施了「異常檢測」(異常檢測)工做流程,其中包括:code
第一步是使用時間序列分解time_decompose()。「計數」列被分解爲「觀察」,「季節」,「趨勢」和「剩餘」列。時間序列分解的默認值是method = "stl",使用黃土平滑器進行季節性分解(參見stats::stl())。的frequency和trend參數是基於使用所述時間序列的時間尺度(或週期性)自動設置tibbletime在引擎蓋下基於函數。blog
## # 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自動爲您選擇。若是要查看所選內容,請進行設置message = TRUE。此外,您能夠經過輸入基於時間的週期(例如「1周」或「2個季度」)來更改選擇,這一般更直觀,能夠肯定有多少觀察屬於時間跨度。引擎蓋下,time_frequency()以及time_trend()基於時間段將這些使用數值tibbletime!索引
下一步是對分解的數據執行異常檢測,特別是「餘數」列。咱們使用了這個anomalize(),它產生了三個新列:「remainder_l1」(下限),「remainder_l2」(上限)和「異常」(是/否標誌)。默認方法是method = "iqr",在檢測異常時快速且相對準確。alpha默認狀況下alpha = 0.05,該參數設置爲,但能夠調整該參數以增長或減小異常頻段的高度,從而使數據更難或更難以變得異常。max_anoms默認狀況下,該參數設置爲max_anoms = 0.2可能異常的20%數據的最大值。這是能夠調整的第二個參數。最後,verbose = FALSE默認狀況下返回一個數據框。嘗試設置verbose = TRUE 以列表的形式獲取異常值報告。事件
## # 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
若是你想一想象正在發生的事情,如今嘗試另外一個繪圖功能是一個好點plot_anomaly_decomposition()。它只適用於單個時間序列,所以咱們只需選擇一個便可查看。「季節」正在消除每週的循環季節性。趨勢是平滑的,這對於消除集中趨勢而不過分擬合是合乎須要的。最後,分析剩餘部分以檢測最重要的異常值的異常。ci
tidyverse_cran_downloads %>% # Anomalize time_decompose(count, method = "stl", frequency = "auto", trend = "auto") %>% anomalize(remainder, method = "iqr", alpha = 0.05, max_anoms = 0.2) %>% # Plot Anomaly Decomposition plot_anomaly_decomposition() + ggtitle("Lubridate Downloads: Anomaly Decomposition")
最後一步是圍繞「觀察」值建立下限和上限。這是工做time_recompose(),它從新組合觀察值周圍的異常的下限和上限。建立了兩個新列:「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 Anomaly Decomposition plot_anomalies(time_recomposed = TRUE) + ggtitle("Lubridate Downloads: Anomalies Detected")
包 中的tsoutliers()功能forecast是在執行預測以前有效收集異常值以進行清潔的好方法。它使用基於STL的離羣值檢測方法,其具備圍繞時間序列分解的餘數的3X內四分位數範圍。它很是快,由於最多有兩次迭代來肯定異常值帶。可是,它沒有設置整潔的工做流程。也不容許調整3X。一些時間序列可能須要更多或更少,這取決於剩餘部分的方差的大小與異常值的大小的關係。
該tsoutliers軟件包很是有效地用於檢測異常的許多傳統預測時間序列。可是,速度是一個問題,特別是在嘗試擴展到多個時間序列或分鐘或秒時間戳數據時。
在審查可用的軟件包時,咱們從中瞭解到全部軟件包的最佳組合:
另外,咱們對本身作了一些改進:
咱們的客戶對此很是滿意,看到咱們能夠繼續構建每一個人均可以享受的新功能和功能使人興奮。
有問題歡迎下方留言!