使用 R 中的 tsoutliers 包检测时间序列中的异常值(LS/AO/TC)。如何以方程格式表示异常值?

机器算法验证 时间序列 预测 有马 异常值
2022-02-08 15:47:20

评论: 首先,我要非常感谢tsoutliers软件包的作者,该软件包实现了 Chen 和 Liu 的时间序列异常值检测,该软件包于 1993 年发表在美国统计协会杂志的开源软件中。R

该包在时间序列数据中迭代检测 5 种不同类型的异常值:

  1. 加性异常值 (AO)
  2. 创新异常值 (IO)
  3. 电平转换 (LS)
  4. 临时变更 (TC)
  5. 季节性水平偏移 (SLS)

更棒的是,这个包从预测包中实现了 auto.arima,因此检测异常值是无缝的。该软件包还可以生成漂亮的图,以便更好地理解时间序列数据。

以下是我的问题:

我尝试使用这个包运行几个示例,效果很好。加性异常值和水平偏移是直观的。但是,关于处理临时变更异常值和创新异常值,我有 2 个问题,我无法理解。

临时变化异常值示例:

考虑以下示例:

library(tsoutliers)
library(expsmooth)
library(fma)

outlier.chicken <- tsoutliers::tso(chicken,types = c("AO","LS","TC"),maxit.iloop=10)
outlier.chicken
plot(outlier.chicken)

该程序正确地检测到以下位置的电平偏移和临时变化。

Outliers:
  type ind time coefhat tstat
1   LS  12 1935   37.14 3.153
2   TC  20 1943   36.38 3.350

以下是情节和我的问题。

  • 如何以方程式格式编写临时更改?(电平位移可以很容易地写成二进制变量,在 1935/Obs 12 之前的任何时间都是 0,而在 1935 和之后的任何时间都是 1。)

包装手册和文章中临时更改的公式如下:

L(B)=11δB

其中为 0.7。我只是在努力将其翻译为上面的示例。δ

  • 我的第二个问题是关于创新异常值,我在实践中从未遇到
    过创新异常值。任何数值示例或案例示例都会非常有帮助。

异常值

编辑: @Irishstat,tsoutliers 函数在识别异常值和建议适当的 ARIMA 模型方面做得很好。查看 Nile 数据集,请参阅下面的 auto.arima 应用程序,然后应用 tsoutliers(默认值包括 auto.arima):

auto.arima(Nile)
Series: Nile 
ARIMA(1,1,1)                    

Coefficients:
         ar1      ma1
      0.2544  -0.8741
s.e.  0.1194   0.0605

sigma^2 estimated as 19769:  log likelihood=-630.63
AIC=1267.25   AICc=1267.51   BIC=1275.04

应用 tsoutliers 函数后,它会识别 LS 异常值和加性异常值,并推荐 ARIMA 顺序 (0,0,0)。

nile.outliers <- tso(Nile,types = c("AO","LS","TC"))
nile.outliers
Series: Nile 
ARIMA(0,0,0) with non-zero mean 

Coefficients:
      intercept       LS29       AO43
      1097.7500  -242.2289  -399.5211
s.e.    22.6783    26.7793   120.8446

sigma^2 estimated as 14401:  log likelihood=-620.65
AIC=1249.29   AICc=1249.71   BIC=1259.71

Outliers:
  type ind time coefhat  tstat
1   LS  29 1899  -242.2 -9.045
2   AO  43 1913  -399.5 -3.306

在此处输入图像描述

1个回答

临时变化 TC 是异常值的一般类型。包文档中给出的方程式以及您编写的方程式是描述此类异常值动态的方程式。您可以通过filter如下所示的函数生成它。将它显示为几个 delta 值是很有启发性的。对于,TC 在一个加性异常值中崩溃;在另一个极端,,TC 就像一个电平转换。δ=0δ=1

tc <- rep(0, 50)
tc[20] <- 1
tc1 <- filter(tc, filter = 0, method = "recursive")
tc2 <- filter(tc, filter = 0.3, method = "recursive")
tc3 <- filter(tc, filter = 0.7, method = "recursive")
tc4 <- filter(tc, filter = 1, method = "recursive")
par(mfrow = c(2,2))
plot(tc1, main = "TC delta = 0")
plot(tc2, main = "TC delta = 0.3")
plot(tc3, main = "TC delta = 0.7")
plot(tc4, main = "TC delta = 1", type = "s")

暂时的变化

在您的示例中,您可以使用该函数outliers.effects来表示检测到的异常值对观察到的系列的影响:

# unit impulse
m1 <- ts(outliers.effects(outlier.chicken$outliers, n = length(chicken), weights = FALSE))
tsp(m1) <- tsp(chicken)
# weighted by the estimated coefficients
m2 <- ts(outliers.effects(outlier.chicken$outliers, n = length(chicken), weights = TRUE))
tsp(m2) <- tsp(chicken)

创新异常值 IO 更为奇特。与 中考虑的其他类型的异常值相反,tsoutliersIO 的影响取决于所选模型和参数估计。这个事实与许多异常值串联起来可能会很麻烦。在算法的第一次迭代中(其中一些异常值的影响可能尚未检测和调整),ARIMA 模型的估计质量可能不足以准确定义 IO。此外,随着算法的进展,可以选择新的 ARIMA 模型。因此,可以在初始阶段使用 ARIMA 模型检测 IO,但最终其动态由在最后阶段选择的另一个 ARIMA 模型定义。

本文档(1) 中表明,在某些情况下,IO 的影响可能会随着其发生日期变得越来越远而增加,这很难解释或假设。

IO 具有有趣的潜力,因为它可以捕捉季节性异常值。中考虑的其他类型的异常值tsoutliers无法捕捉季节性模式。然而,在某些情况下,最好搜索可能的季节性水平变化,SLS,而不是 IO(如前面提到的文档中所示)。

IO有一个吸引人的解释。它有时被理解为一个加性异常值,它影响扰动项,然后根据 ARIMA 模型的动态在序列中传播。从这个意义上说,IO 就像一个加性异常值,它们都影响单个观察,但 IO 是扰动项中的脉冲,而 AO 是直接添加到 ARIMA 模型或数据生成过程生成的值的脉冲. 异常值是否影响创新或超出干扰项可能是一个讨论问题。

在之前的参考资料中,您可能会发现一些检测到 IO 的真实数据示例。


(1)时间序列中的季节性异常值。Regina Kaiser 和 Agustín Maravall。文件 20.II.2001。