在R中如何用nnetar实现样本外一步预测并评估其性能?
Got it, let's break down how to replicate your auto.arima out-of-sample one-step forecast workflow with nnetar in R. The core difference is that nnetar (a neural network-based time series model) doesn't have a direct equivalent to the Arima() function's model parameter for reusing a pre-trained model on new data. Instead, we need to use a rolling prediction approach since neural network time series models rely on lagged values as inputs.
Step 1: Prepare Train/Test Data
First, we'll stick with your original train/test split to keep consistency:
library(forecast) library(nnet) # Prepare train and test sets train <- lynx[1:100] test <- lynx[101:length(lynx)]
Step 2: Train the nnetar Model
We start by fitting the neural network model on the training data:
# Train nnetar model on the training set train_nnet <- nnetar(train)
Step 3: Generate One-Step Out-of-Sample Forecasts
Unlike auto.arima where you can pass a pre-trained model to Arima() to get fitted values on the test set, nnetar requires us to iteratively predict one step at a time, updating our history with the actual test value after each prediction. This mimics the "one-step ahead" logic where each forecast uses the most recent real data:
# Initialize a vector to store our one-step forecasts one_step_nnet <- numeric(length(test)) # Start with the full training data as our initial history current_history <- train # Loop through each observation in the test set for (i in seq_along(test)) { # Predict one step ahead using the current history fcast <- forecast(train_nnet, h = 1, newdata = current_history) # Store the forecast value one_step_nnet[i] <- fcast$mean[1] # Update history with the actual test value (so next prediction uses real data) current_history <- c(current_history, test[i]) }
Step 4: Compare with Your auto.arima Results
To verify, you can plot both sets of one-step forecasts alongside the actual data:
# Plot actual values vs both forecast sets plot(lynx, main = "Lynx Population: Actual vs One-Step Forecasts", lwd = 2) lines(c(rep(NA, length(train)), one_step_nnet), col = "darkred", lwd = 2, lty = 2) lines(c(rep(NA, length(train)), one.step), col = "steelblue", lwd = 2, lty = 2) legend("topleft", legend = c("Actual", "nnetar One-Step", "auto.arima One-Step"), col = c("black", "darkred", "steelblue"), lwd = 2, lty = c(1,2,2))
Why Your Previous nnetar Code Might Have Failed
If you tried to directly fit nnetar(test) or use forecast(train_nnet, h=20) without updating history, you'd get multi-step forecasts (not one-step ahead). Multi-step forecasts rely on previous predictions instead of real data, which is why they don't match the logic of your auto.arima workflow.
Bonus: Efficient Cross-Validation with tsCV
If you want to calculate forecast errors directly (instead of just getting forecast values), the forecast package's tsCV function simplifies rolling one-step validation:
# Calculate one-step forecast errors using cross-validation nnet_cv_errors <- tsCV(lynx, function(x) nnetar(x), h = 1) # Extract errors for the test set (indices 101 to end) test_errors <- nnet_cv_errors[101:length(lynx)]
内容的提问来源于stack exchange,提问作者Soson

