4

我在大量时间序列上使用一个大(isplit)循环来测试 ARIMA 模型。为此,我正在使用包中的auto.arima功能forecast

为此,我创建了一个函数,用于遍历所有时间序列,同时跟踪进度并存储拟合模型和统计数据(例如准确性和模型参数)。现在我正在处理auto.arima函数生成的错误。更准确地说;由 OCSB 季节性测试引起。

我将此函数用于“每月”时间序列以及“每周”时间序列。对于每月时间序列 a 没有问题(几乎 50000,包括很多“零”值)。对于每周时间序列,我遇到了问题。但我无法找到错误的真正原因。

我试图重新创建错误。我认为它与许多 0(或相同)值与 52 频率周期相结合有关。但我仍然不能把矛头指向问题所在。

请参阅下面的示例。一些信息:时间序列集是每周值(频率 = 52),从 2010 年第 1 周开始。长度为 122 个样本(直到 2012 年第 18 周)。因此我测试了 122 的长度,我可以为此生成错误。我仍然认为这与频率和“运行相同的值”有关......

对于某些错误会产生,对于某些不会。

例1【随机数,长度=122】>没问题:

ts_element <- ts(sample(0:30, 122, replace=TRUE), frequency = 52, start = c(2010, 1))
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)

示例 2 [只有 0 个值,长度 = 122] > OCSB 测试错误(通常我会假设一个不同的错误...参见示例 3):

ts_element <- ts(sample(0:0, 122, replace=TRUE), frequency = 52, start = c(2010, 1))
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)
Error in OCSBtest(x, m) : subscript out of bounds

示例 3 [只有 0 个值,长度 = 100] > '零/相等值' 错误,我假设这个,这个例子不是问题,但要指出长度是相关的(与示例 2 比较):

ts_element <- ts(sample(0:0, 100, replace=TRUE), frequency = 52, start = c(2010, 1))
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)
Error in if (PVAL == min(tablep)) warning("p-value smaller than printed p-value") else warning("p-value greater     than printed p-value") : 
  missing value where TRUE/FALSE needed

示例 4 [与 ex.3 几乎相同,但有一个非 0 值,长度 = 100] > 没有问题了:

ts_element[30] <- 1
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)

示例 5 [与 ex.4 几乎相同,但长度=122] > OCSB 测试错误:

ts_element <- ts(sample(0:0, 122, replace=TRUE), frequency = 52, start = c(2010, 1))
ts_element[30] <- 1
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)
Error in OCSBtest(x, m) : subscript out of bounds

示例 6 [随机 1 和 0,长度=122] > 没问题:

ts_element <- ts(sample(0:1, 122, replace=TRUE), frequency = 52, start = c(2010, 1))
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)

例 7【随机数,长度小于 50】> 没问题:

ts_element <- ts(sample(1:34, 50, replace=TRUE), frequency = 52, start = c(2010, 1))
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)

有谁知道 OCSB 越界错误的原因是什么?如何识别?

主要问题是,每当我在本文开头描述的函数中出现此错误时,该函数不会输出我收集的所有信息。因此,等待的时间是徒劳的。因此,如果无法找到根本原因,我还可以通过一些代码来处理错误以“忽略”它们(跳过该时间序列)并走得更远。或者忽略,但仍然输出当时收集到的信息。

有怎样的解决方法?

注意:零错误不是问题。我在我的功能中介绍了这一点。

4

1 回答 1

10

很好的问题,并且解释得很好。您在提交之前清楚地考虑了这一点。

您的示例中的问题是由于处理充满零的时间序列的许多问题(在我看来是错误)。

通常,您应该使用该debug命令来单步执行您的代码。例如,尝试调试为 运行的五个主要函数auto.arima

debug(auto.arima)
debug(nsdiffs)
debug(forecast:::OCSBtest)
debug(lm)
debug(lm.fit)

(用于Q退出和undebug停止调试函数)然后尝试运行示例 2中的代码

ts_element <- ts(sample(0:0, 122, replace=TRUE), frequency = 52, start = c(2010, 1))
fit <- auto.arima(ts_element, trace=FALSE, seasonal.test="ocsb", allowdrift=TRUE, stepwise=TRUE)

经过大量的压力Enter,你最终会到达 R 失败的地步。在这种情况下,这是lm.fit. 如果所有系数都为零,那么由于某种原因,它将它们转换为NA. 当OCSBtest函数试图提取系数时,它发现矩阵是空的,并告诉你它不是一个合适的索引。

我会告诉你向 R-bugs 报告这个...但是当涉及到base. 他们可能会告诉您这是“用户错误”,并且您不应该将回归模型拟合为全零(叹气)。

示例 3的第一个问题似乎是nsdiffs页面中未记录的功能,该功能描述了该 forecast::OCSBtest功能。看起来您的时间序列必须大于周期的 2 倍 + 5,否则将不会运行季节性差异。在示例 2中这是正确的,但在示例 3中则不然。实际上,函数中代码的第一部分是:

if (length(time.series) < (2 * period + 5)) {
    return(0)
}

阅读页面中列出的两个 Osborn 参考资料nsdiffs,也许它在某处提到它。让作者forecast知道是个好主意,这样他们就可以将其包含在文档中的某个地方。甚至可能会发出警告,并可以选择将其关闭。

示例 3与示例 2有不同的错误,因为示例 3立即退出nsdiffs函数,然后在ndiff执行差分的函数中继续失败。ndiff似乎有一个错误,如果平方差之和为零(因为系列为零),则会导致除以零错误。下面是ndiff函数中的相关代码:

s2 <- .C("R_pp_sum", as.vector(e, mode = "double"), as.integer(n), as.integer(l), s2 = as.double(s2), PACKAGE = "tseries")$s2
STAT <- eta/s2 # Becomes NaN
PVAL <- approx(table, tablep, STAT, rule = 2)$y # Also NaN
if (is.na(approx(table, tablep, STAT, rule = 1)$y)) if (PVAL == 
min(tablep)) warning("p-value smaller than printed p-value") else warning("p-value greater than printed p-value") # Bombs

示例 4成功,因为s2从不为零。一个简单的解决方法是s2在除法之前检查是否为零。

示例 5失败的原因与示例 2大致相同。它进入nsdiff函数是因为它的长度大于2*period+5,然后失败,因为lm.fit当它们全为零时不返回系数。

示例 6成功,因为lm.fit现在将正确返回系数,因为它们并非全为零,因为您的时间序列混合了 1 和 0。

示例 7成功,因为nsdiff没有运行(因为序列太小)并且ndiff不再导致除以零,因为平方差之和不会为零。

总之,您的示例显示了两个错误。一个在ndiff时间序列始终为零时,另一个在lm.fit协变量都为零时的函数中。此外,应该更新文档以告诉您,如果时间序列的长度小于您使用 'ocsb' 选项nsdiff的长度,它将不会运行(但也许这在参考文献中有记录)。2*period+5

于 2012-06-05T22:14:51.553 回答