【时间序列】时序预测竞赛之异常检测算法综述
本文將介紹在時間序列預測相關問題中常見的異常檢測算法,可以很大程度上幫助改善最終預測效果。
異常分類
時間序列的異常檢測問題通常表示為相對于某些標準信號或常見信號的離群點。雖然有很多的異常類型,但是我們只關注業務角度中最重要的類型,比如意外的峰值、下降、趨勢變化以及等級轉換(level shifts)。
常見的異常有如下幾種:
革新性異常:innovational outlier (IO),造成離群點干擾不僅作用于X(T),而且影響T時刻以后序列的所有觀察值。
附加性異常:additive outlier (AO),造成這種離群點的干擾,只影響該干擾發生的那一個時刻T上的序列值,而不影響該時刻以后的序列值。
水平移位異常:level shift (LS),造成這種離群點的干擾是在某一時刻T,系統的結構發生了變化,并持續影響T時刻以后的所有行為,在數列上往往表現出T時刻前后的序列均值發生水平位移。
暫時變更異常temporary change (TC):造成這種離群點的干擾是在T時刻干擾發生時具有一定初始效應,以后隨時間根據衰減因子的大小呈指數衰減。
上面的解釋可能不太容易理解,我們結合圖片來看一下:
通常,異常檢測算法應該將每個時間點標記為異常/非異常,或者預測某個點的信號,并衡量這個點的真實值與預測值的差值是否足夠大,從而將其視為異常。使用后面的方法,你將能夠得到一個可視化的置信區間,這有助于理解為什么會出現異常并進行驗證。
常見異常檢測方法
從分類看,當前發展階段的時序異常檢測算法和模型可以分為一下幾類:
統計模型:優點是復雜度低,計算速度快,泛化能力強悍。因為沒有訓練過程,即使沒有前期的數據積累,也可以快速的投入生產使用。缺點是準確率一般。但是這個其實是看場景的,并且也有簡單的方法來提高業務層面的準確率。這個后面會提到。
機器學習模型:魯棒性較好,準確率較高。需要訓練模型,泛化能力一般。
深度學習模型:普遍需要喂大量的數據,計算復雜度高。整體看,準確性高,尤其是近段時間,強化學習的引入,進一步鞏固其準確性方面的領先優勢。
3-Sigma
3-Sigma原則又稱為拉依達準則,該準則定義如下:假設一組檢測數據只含有隨機誤差,對原始數據進行計算處理得到標準差,然后按一定的概率確定一個區間,認為誤差超過這個區間的就屬于異常值。
使用3-Sigma的前提是數據服從正態分布,滿足這個條件之后,在3-Sigma范圍(μ–3σ,μ+3σ)內99.73%的為正常數據,其中σ代表標準差,μ代表均值,x=μ為圖形的對稱軸。下面是3-Sigma的Python實現:
import numpy as np def three_sigma(df_col):'''df_col:DataFrame數據的某一列'''rule = (df_col.mean() - 3 * df_col.std() > df_col) | (df_col.mean() + 3 * df_col.std() < df_col)index = np.arange(df_col.shape[0])[rule]out_range = df_col.iloc[index]return out_range對于異常值檢測出來的結果,有多種處理方式,如果是時間序列中的值,那么我們可以認為這個時刻的操作屬于異常的;如果是將異常值檢測用于數據預處理階段,處理方法有以下四種:
刪除帶有異常值的數據;
將異常值視為缺失值,交給缺失值處理方法來處理;
用平均值進行修正;
當然我們也可以選擇不處理。
Grubbs測試
Grubbs’Test為一種假設檢驗的方法,常被用來檢驗服從正太分布的單變量數據集(univariate data set)Y 中的單個異常值。若有異常值,則其必為數據集中的最大值或最小值。原假設與備擇假設如下:
H0: 數據集中沒有異常值
H1: 數據集中有一個異常值
使用Grubbs測試需要總體是正態分布的。算法流程:
樣本從小到大排序
求樣本的mean和dev
計算min/max與mean的差距,更大的那個為可疑值
求可疑值的z-score (standard score),如果大于Grubbs臨界值,那么就是outlier
Grubbs臨界值可以查表得到,它由兩個值決定:檢出水平α(越嚴格越小),樣本數量n,排除outlier,對剩余序列循環做 1-4 步驟。由于這里需要的是異常判定,只需要判斷tail_avg是否outlier即可。
from outliers import smirnov_grubbs as grubbs print(grubbs.test([8, 9, 10, 1, 9], alpha=0.05)) print(grubbs.min_test_outliers([8, 9, 10, 1, 9], alpha=0.05)) print(grubbs.max_test_outliers([8, 9, 10, 1, 9], alpha=0.05)) print(grubbs.max_test_indices([8, 9, 10, 50, 9], alpha=0.05))S-ESD與S-H-ESD
鑒于時間序列數據具有周期性(seasonal)、趨勢性(trend),異常檢測時不能作為孤立的樣本點處理;故而Twitter的工程師提出了S- ESD (Seasonal ESD)與S-H-ESD (Seasonal Hybrid ESD)算法,將ESD擴展到時間序列數據。
STL分解
STL (Seasonal-Trend decomposition procedure based on Loess) 為時序分解中一種常見的算法,基于LOESS將某時刻的數據Yv分解為趨勢分量(trend component)、季節性分量(seasonal component)和殘差(remainder component):
?
由上到下依次為:原始時間序列和使用 STL 分解得到的季節變化部分、趨勢變化部分以及殘差部分。
STL分為內循環(inner loop)與外循環(outer loop),其中內循環主要做了趨勢擬合與周期分量的計算。假定T(k)v、Sv(k)為內循環中第k-1次pass結束時的趨勢分量、周期分量,初始時T(k)v=0;并有以下參數:
n(i)內層循環數
n(o)外層循環數
n(p)為一個周期的樣本數
n(s)為Step 2中LOESS平滑參數
n(l)為Step 3中LOESS平滑參數
n(t)為Step 6中LOESS平滑參數
每個周期相同位置的樣本點組成一個子序列(subseries),容易知道這樣的子序列共有共有n(p)個,我們稱其為cycle-subseries。
Python的statsmodels實現了一個簡單版的時序分解,通過加權滑動平均提取趨勢分量,然后對cycle-subseries每個時間點數據求平均組成周期分量:
使用示例:
import numpy as np import pandas as pd from statsmodels.tsa.seasonal import seasonal_decompose import matplotlib.pyplot as plt # Generate some data np.random.seed(0) n = 1500 dates = np.array('2019-01-01', dtype=np.datetime64) + np.arange(n) data = 12 * np.sin(2 * np.pi * np.arange(n) / 365) + np.random.normal(12, 2, 1500) df = pd.DataFrame({'data': data}, index=dates) # Reproduce the example in OP seasonal_decompose(df, model='additive', period=1).plot() plt.show()S-ESD
STL將時間序列數據分解為趨勢分量、周期分量和余項分量。想當然的解法——將ESD運用于STL分解后的余項分量中,即可得到時間序列上的異常點。但是,我們會發現在余項分量中存在著部分假異常點(spurious anomalies)。如下圖所示:
在紅色矩形方框中,向下突起點被誤報為異常點。為了解決這種假陽性降低準確率的問題,S-ESD算法用中位數(median)替換掉趨勢分量;
使用示例:
import numpy as np import sesd ts = np.random.random(100) # Introduce artificial anomalies ts[14] = 9 ts[83] = 10 outliers_indices = sesd.seasonal_esd(ts, periodicity=20, hybrid=True, max_anomalies=2) for idx in outliers_indices:print(f'Anomaly index: {idx}, anomaly value: {ts[idx]}')移動平均/加權移動平均/指數加權移動平均
移動平均 moving average
給定一個時間序列和窗口長度N,moving average等于當前data point之前N個點(包括當前點)的平均值。不停地移動這個窗口,就得到移動平均曲線。
累加移動平均 cumulative moving average
設{xi:i≥1}是觀察到的數據序列。累積移動平均線是所有數據的未加權平均值。如果若干天的值是x1,…,xi,那么:
加權移動平均 weighted moving average
加權移動平均值是先前w個數據的加權平均值
指數加權移動平均 exponential weighted moving average
指數移動與移動平均有些不同:
并沒有時間窗口,用的是從時間序列第一個data point到當前data point之間的所有點。
每個data point的權重不同,離當前時間點越近的點的權重越大,歷史時間點的權重隨著離當前時間點的距離呈指數衰減,從當前data point往前的data point,權重依次為
該算法可以檢測一個異常較短時間后發生另外一個異常的情況,異常持續一段時間后可能被判定為正常。
ARIMA 模型
自回歸移動平均模型(ARIMA)是一種設計上非常簡單的方法,但其效果足夠強大,可以預測信號并發現其中的異常。該方法的思路是從過去的幾個數據點來生成下一個數據點的預測,在過程中添加一些隨機變量(通常是添加白噪聲)。以此類推,預測得到的數據點可以用來生成新的預測。很明顯:它會使得后續預測信號數據更平滑。使用這種方法最困難的部分是選擇差異數量、自回歸數量和預測誤差系數。另一個障礙是信號經過差分后應該是固定的。也就是說,這意味著信號不應該依賴于時間,這是一個比較顯著的限制。
異常檢測是利用離群點來建立一個經過調整的信號模型,然后利用t-統計量來檢驗該模型是否比原模型能更好的擬合數據。
在這種情況下,你可以找到適合信號的 ARIMA 模型,它可以檢測出所有類型的異常。
神經網絡
與CART方法一樣,神經網絡有兩種應用方式:監督學習和無監督學習。我們處理的數據是時間序列,所以最適合的神經網絡類型是 LSTM。如果構建得當,這種循環神經網絡將可以建模實現時間序列中最復雜的依賴關系,包括高級的季節性依賴關系。如果存在多個時間序列相互耦合,該方法也非常有用。該領域還在研究中,可以參考這里,構建時序模型需要大量的工作。構建成功完成后,就可能在精確度方面取得優異的成績。
往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯 獲取本站知識星球優惠券,復制鏈接直接打開: https://t.zsxq.com/qFiUFMV 本站qq群704220115。加入微信群請掃碼:總結
以上是生活随笔為你收集整理的【时间序列】时序预测竞赛之异常检测算法综述的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 精通C++之前,你必须知道的几件事!
- 下一篇: 【Python基础】13个知识点,系统整