这篇文章描述了一种对涉及季节性和趋势成分的时间序列的异常点进行建模的方法。我们将对一种叫做STL的算法进行研究,STL是 "使用_LOESS_(局部加权回归)的季节-趋势分解 "的缩写,以及如何将其应用于异常检测。
其基本思想是,如果你有一个有规律的时间序列,你可以通过STL算法运行该序列,并分离出规律的模式。剩下的是 "不规则的",而异常检测相当于判定不规则性是否足够大。
例子:航空乘客,1949-1960
让我们在数据集上运行该算法,该数据集给出了1949-1960年期间每月的航空公司乘客数量。首先,这是未经修改的时间序列。
plot(y)
这里显然有一个规律性的模式,但是在这个序列中没有任何明显的下降,无法在异常检测中显示出来。所以我们将设置一个。
y\[40\] = 150
跌幅足够大,我们希望异常检测能发现它,但又不至于大到你只看一眼图就会发现。现在让我们通过STL检查它。
plot(fit)
首先,我不是在y上运行STL,而是在log(y)上。
该算法将序列分解为三个部分:季节性、趋势和剩余成分。季节性是周期性成分,趋势是一般的上升/下降,剩余成分是剩下的趋势成分。季节性和趋势共同构成了序列的 "常规 "部分,因此是我们在异常检测过程中要剔除的部分。
剩余部分基本上是原始序列的正常化版本,所以这是我们监测异常情况的部分。剩余序列的下降是很明显的。我们在1952年初设置的异常下降很可能算在内。
我们还可以调整每一时期的观测值数量,负责分离季节性和趋势成分的平滑方法,拟合模型的 "稳健性"(即对异常值不敏感)等等。这些参数中的大多数需要对基础算法的工作原理有一定的了解。
下面是一些显示实际数据与阈值的代码。
data <- merge(df, ba, by.x='x')ggplot(data) + geom(aes(x=x, ymin=ymin, ymax=ymax))
再次,聪明如你可能会注意到通过exp()进行的逆变换。我们现在讨论这个问题。
为什么要进行对数和逆变换?
并非所有的分解都涉及对数变换,但这个分解却涉及。其原因与分解的性质有关。STL的分解总是加法的。
y = s + t + r
但对于某些时间序列,乘法分解更适合。
y = str
这种情况发生在销售数据中,季节性成分的振幅随着趋势的增加而增加。这实际上是乘法序列的标志,航空旅客序列也表现出这种模式。为了处理这个问题,我们对原始值进行对数转换,这使我们进入加法领域,在那里我们可以进行STL分解。当我们完成后,我们再进行逆变换,回到原始序列。
多重季节性的情况如何?
一些时间序列有一个以上的季节性。例如,在酒店预订时间序列有三个季节性:每日、每周和每年。
虽然有一些程序可以生成具有多个季节性成分的分解,但STL并没有这样做。最高频率的季节性被作为季节性成分,而任何较低频率的季节性都被吸收到趋势中。