R错误:时间序列/向量长度不匹配

dtcbnfnu  于 2023-03-05  发布在  其他
关注(0)|答案(1)|浏览(309)
    • bounty将在5天后过期**。回答此问题可获得+50的声誉奖励。stats_noob正在寻找来自声誉良好来源的答案:你好!我正在尝试使用LOOCV(留一个我们的交叉验证)为ARIMA时间序列模型使用R。我不知道我是否正确地这样做-有人能帮助我吗?谢谢!

我有以下数据集:

weeks <- rep(seq(as.Date("2010-01-01"), as.Date("2023-01-01"), by = "week"), each = 1)
counts <- rpois(length(weeks), lambda = 50)
df <- data.frame(Week = as.character(weeks), Count = counts)

我试图用一个时间序列模型来拟合这些数据,并执行LOOCV(Leave One Out Cross Validation,留一交叉验证),即:

  • 我想使模型拟合70%的数据(按时间顺序)
  • 预测下一个点(horizon = 1)
  • 记录此预测的误差
  • 预测下一个点,记录误差
  • 重复直至完成剩余30%-记录最终平均误差(RMSE、MAE)

使用这篇文章作为参考(http://freerangestats.info/blog/2019/07/20/time-series-cv),我尝试编写一个循环来执行这个过程。
首先,我设置了循环的要求:

# Split data into training and test sets
train_size <- floor(0.7 * nrow(df))
train <- df[1:train_size, ]
test <- df[(train_size + 1):nrow(df), ]

# Fit ARIMA model to training data
model <- auto.arima(train$Count)

# Initialize vector to store prediction errors
errors <- vector("numeric", length = nrow(test))

rmse_vec <- numeric()
mae_vec <- numeric()

接下来,我尝试运行循环:

# Loop over test set
for (i in seq(train_end+1, n)) {
    
    # Split data into training and validation sets
    train <- df[1:(i-1), ]
    val <- df[i:(i+1), ]
    
    # Fit ARIMA model to training data
    model <- auto.arima(train$Count)
    
    # Forecast one step ahead using the model and record error
    fc <- forecast(model, h = 1)
    error <- val$Count - fc$mean
    
    # Record RMSE and MAE
    rmse_vec[i - train_end - 1] <- sqrt(mean(error^2))
    mae_vec[i - train_end - 1] <- mean(abs(error))
    
    # Update training data with actual count
    train$Count <- c(train$Count, val$Count[1])
}

# Compute mean RMSE and MAE
mean_rmse <- mean(rmse_vec)
mean_mae <- mean(mae_vec)
    • 问题:**但是,此代码显示以下错误:
Error in `-.default`(val$Count, fc$mean) : 
  time-series/vector length mismatch

有人能告诉我如何解决这个问题吗?我对时间序列模型的LOOCV操作正确吗?
谢谢!

      • 注意**:我不确定LOOCV是不是通常在时间序列模型上执行的--也许这里有人知道?
unguejic

unguejic1#

出现您看到的错误是因为val$Countfc$mean的长度不同。val$Count是单个值,而fc$mean是长度为1的向量。因此,当您尝试将它们相减时,会出现长度不匹配错误。
要解决这个问题,你可以使用as.numeric(fc$mean)fc$mean[1]来提取fc$mean的值,这会给予你一个可以从val$Count中减去的值,下面是修正后的循环:

# Loop over test set
for (i in seq(train_size + 1, nrow(df))) {
    
    # Split data into training and validation sets
    train <- df[1:(i-1), ]
    val <- df[i, ]
    
    # Fit ARIMA model to training data
    model <- auto.arima(train$Count)
    
    # Forecast one step ahead using the model and record error
    fc <- forecast(model, h = 1)
    error <- val$Count - as.numeric(fc$mean)
    
    # Record RMSE and MAE
    rmse_vec[i - train_size] <- sqrt(mean(error^2))
    mae_vec[i - train_size] <- mean(abs(error))
    
}

# Compute mean RMSE and MAE
mean_rmse <- mean(rmse_vec)
mean_mae <- mean(mae_vec)

注意,我对循环做了一些其他的修改。首先,我把val <- df[i:(i+1), ]修改为val <- df[i, ]。这是因为我们想要预测下一个点(horizon = 1),所以我们只需要提前一步预测。第二,我将rmse_vec[i - train_end - 1]更改为rmse_vec[i - train_size],将mae_vec[i - train_end - 1]更改为mae_vec[i - train_size],这是因为您的代码中没有定义train_end,但是定义了train_size,并且train_size表示训练集中的行数。
关于是否正确地对时间序列模型执行LOOCV,您正在使用的方法称为滚动原点或移动窗口交叉验证。LOOCV涉及将模型拟合到除一个观测之外的所有数据,并使用该观测验证模型。滚动原点是一种更实用的时间序列数据方法,因为它考虑了数据的时态结构。

相关问题