- 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是不是通常在时间序列模型上执行的--也许这里有人知道?
1条答案
按热度按时间unguejic1#
出现您看到的错误是因为
val$Count
和fc$mean
的长度不同。val$Count
是单个值,而fc$mean
是长度为1的向量。因此,当您尝试将它们相减时,会出现长度不匹配错误。要解决这个问题,你可以使用
as.numeric(fc$mean)
或fc$mean[1]
来提取fc$mean
的值,这会给予你一个可以从val$Count
中减去的值,下面是修正后的循环:注意,我对循环做了一些其他的修改。首先,我把
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涉及将模型拟合到除一个观测之外的所有数据,并使用该观测验证模型。滚动原点是一种更实用的时间序列数据方法,因为它考虑了数据的时态结构。