Tout d'abord, sachez que forecast
calcule les prédictions hors échantillon, mais vous êtes intéressé par les observations dans l'échantillon.
Le filtre de Kalman gère les valeurs manquantes. Ainsi, vous pouvez prendre la forme d'espace d'état du modèle ARIMA à partir de la sortie renvoyée par forecast::auto.arima
ou stats::arima
et la transmettre à KalmanRun
.
Modifier (correction dans le code basé sur la réponse de stats0007)
Dans une version précédente, je prenais la colonne des états filtrés liés à la série observée, mais je devrais utiliser la matrice entière et faire l'opération de matrice correspondante de l'équation d'observation, . (Merci à @ stats0007 pour les commentaires.) Ci-dessous, je mets à jour le code et trace en conséquence.yt= Zαt
J'utilise un ts
objet comme une série d'échantillons au lieu de zoo
, mais il devrait être le même:
require(forecast)
# sample series
x0 <- x <- log(AirPassengers)
y <- x
# set some missing values
x[c(10,60:71,100,130)] <- NA
# fit model
fit <- auto.arima(x)
# Kalman filter
kr <- KalmanRun(x, fit$model)
# impute missing values Z %*% alpha at each missing observation
id.na <- which(is.na(x))
for (i in id.na)
y[i] <- fit$model$Z %*% kr$states[i,]
# alternative to the explicit loop above
sapply(id.na, FUN = function(x, Z, alpha) Z %*% alpha[x,],
Z = fit$model$Z, alpha = kr$states)
y[id.na]
# [1] 4.767653 5.348100 5.364654 5.397167 5.523751 5.478211 5.482107 5.593442
# [9] 5.666549 5.701984 5.569021 5.463723 5.339286 5.855145 6.005067
Vous pouvez tracer le résultat (pour toute la série et pour toute l'année avec des observations manquantes au milieu de l'échantillon):
par(mfrow = c(2, 1), mar = c(2.2,2.2,2,2))
plot(x0, col = "gray")
lines(x)
points(time(x0)[id.na], x0[id.na], col = "blue", pch = 19)
points(time(y)[id.na], y[id.na], col = "red", pch = 17)
legend("topleft", legend = c("true values", "imputed values"),
col = c("blue", "red"), pch = c(19, 17))
plot(time(x0)[60:71], x0[60:71], type = "b", col = "blue",
pch = 19, ylim = range(x0[60:71]))
points(time(y)[60:71], y[60:71], col = "red", pch = 17)
lines(time(y)[60:71], y[60:71], col = "red")
legend("topleft", legend = c("true values", "imputed values"),
col = c("blue", "red"), pch = c(19, 17), lty = c(1, 1))
Vous pouvez répéter le même exemple en utilisant le lisseur Kalman au lieu du filtre Kalman. Il vous suffit de changer ces lignes:
kr <- KalmanSmooth(x, fit$model)
y[i] <- kr$smooth[i,]
Le traitement des observations manquantes au moyen du filtre de Kalman est parfois interprété comme une extrapolation de la série; lorsque le lisseur de Kalman est utilisé, les observations manquantes seraient remplies par interpolation dans la série observée.