【问题标题】:Timeseries Crossvalidation in R: using tsCV() with tslm()-ModelsR 中的时间序列交叉验证:使用 tsCV() 和 tall()-模型
【发布时间】:2018-05-09 14:30:30
【问题描述】:

我目前正在尝试使用时间序列交叉验证来评估 tslm 模型。我想使用一个固定模型(没有参数重新估计)来查看去年评估期的 1 到 3 步的超前水平预测。

我无法从预测库中获取 tsCVtslm 以使其正常工作。我错过了什么?

library(forecast)
library(ggfortify)

AirPassengers_train <- head(AirPassengers, 100)
AirPassengers_test  <- tail(AirPassengers, 44)

## Holdout Evaluation
n_train <- length(AirPassengers_train)
n_test  <- length(AirPassengers_test)
pred_train <- ts(rnorm(n_train))
pred_test  <- ts(rnorm(n_test))

fit <- tslm(AirPassengers_train ~ trend + pred_train)

forecast(fit, newdata = data.frame(pred_train = pred_test)) %>% 
  accuracy(AirPassengers_test)
#>                        ME     RMSE      MAE       MPE     MAPE     MASE
#> Training set 1.135819e-15 30.03715 23.41818 -1.304311 10.89785 0.798141
#> Test set     3.681350e+01 76.39219 55.35298  6.513998 11.96379 1.886546
#>                   ACF1 Theil's U
#> Training set 0.6997632        NA
#> Test set     0.7287923  1.412804


## tsCV Evaluation
fc_reg <- function(x) forecast(x, newdata = data.frame(pred_train = pred_test),
                               h = h, model = fit)

tsCV(AirPassengers_test, fc_reg, h = 1)
#>      Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
#> 1957                  NA  NA  NA  NA  NA  NA  NA  NA
#> 1958  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 1959  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
#> 1960  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA


forecast(AirPassengers_test, newdata = data.frame(pred_train = pred_test),
         h = 1, model = fit)
#> Error in forecast.ts(AirPassengers_test, newdata = data.frame(pred_train = pred_test),
#> : Unknown model class

我有一种感觉,https://gist.github.com/robjhyndman/d9eb5568a78dbc79f7acc49e22553e96 是相关的。我将如何将其应用于上述场景?

【问题讨论】:

  • 您最终找到了这个问题的答案吗?下面的代码返回错误。

标签: r cross-validation forecasting


【解决方案1】:

对于时间序列交叉验证,您应该为每个训练集拟合一个单独的模型,而不是传递现有模型。对于预测变量,该函数需要能够在拟合每个模型时抓取相关元素,并在生成预测时抓取其他元素。

以下将起作用。

fc <- function(y, h, xreg)
{
  if(NROW(xreg) < length(y) + h)
    stop("Not enough xreg data for forecasting")
  X <- xreg[seq_along(y),]
  fit <- tslm(y ~ X)
  X <- xreg[length(y)+seq(h),]
  forecast(fit, newdata=X)
}

# Predictors of the same length as the data
# and with the same time series characteristics.    
pred <- ts(rnorm(length(AirPassengers)), start=start(AirPassengers),
           frequency=frequency(AirPassengers))

# Now pass the whole time series and the corresponding predictors 
tsCV(AirPassengers, fc, xreg=pred)

如果您有多个预测变量,则xreg 应该是一个矩阵。

【讨论】:

  • 非常感谢!但是,为什么在生成起源晚于训练样本的预测时,没有“修复” tslm 的系数?我知道,在评估过程中,训练数据仍然是(稍微)更长的新训练数据的一部分,但在我看来,允许模型在向前滚动时(稍微)更改其参数。
  • 这就是交叉验证。您将模型重新拟合到每个训练集。见otexts.org/fpp2/accuracy.html
  • @RobHyndman 为什么模型的“趋势”术语下降了?考虑到 h > 0,它似乎仍然有用?
  • 对包的更改意味着代码返回了 NA。我已经更新了示例以再次工作。这个例子并不是一个好的模型,只是展示了如何编写代码。
【解决方案2】:

我来这里是为了发布针对同一问题的丑陋解决方法(并可能找出问题所在):

myxreg<-regmat[,c("xvar1","xvar2")]


flm_xreg<-function(x,h,xreg,newxreg){
  forecast(Arima(x,order=c(0,0,0),xreg=xreg),xreg=newxreg)
}

e<-tsCV(regmat[,"yvar"],flm_xreg,h=14,xreg=myexreg)

【讨论】:

    【解决方案3】:

    我最终使用了一个函数来预测趋势。我不确定这是否正确指定,但 rmse 看起来是正确的。

    flm <- function(y, h) { forecast(tslm(y ~ trend, lambda=0), h=h) }
    
    e <- tsCV(tsDF, flm, h=6)
    sqrt(mean(e^2, na.rm=TRUE))
    

    @robhyndman

    【讨论】:

      猜你喜欢
      • 2021-02-26
      • 2020-05-30
      • 2020-07-20
      • 1970-01-01
      • 2018-10-10
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多