Pertama, perlu diketahui bahwa forecast
menghitung prediksi out-of-sample tetapi Anda tertarik pada observasi in-sample.
Filter Kalman menangani nilai yang hilang. Dengan demikian Anda dapat mengambil bentuk ruang keadaan model ARIMA dari output yang dikembalikan oleh forecast::auto.arima
atau stats::arima
dan diteruskan ke KalmanRun
.
Edit (perbaiki dalam kode berdasarkan jawaban oleh stats0007)
Dalam versi sebelumnya saya mengambil kolom dari status yang disaring terkait dengan seri yang diamati, namun saya harus menggunakan seluruh matriks dan melakukan operasi matriks yang sesuai dari persamaan pengamatan, . (Terima kasih kepada @ stats0007 untuk komentarnya.) Di bawah ini saya memperbarui kode dan plot sesuai.yt=Zαt
Saya menggunakan ts
objek sebagai seri sampel, bukan zoo
, tetapi harus sama:
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
Anda dapat memplot hasilnya (untuk seluruh seri dan sepanjang tahun dengan pengamatan yang hilang di tengah sampel):
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))
Anda dapat mengulangi contoh yang sama menggunakan Kalman lebih halus, bukan filter Kalman. Yang perlu Anda ubah adalah baris-baris ini:
kr <- KalmanSmooth(x, fit$model)
y[i] <- kr$smooth[i,]
Berurusan dengan pengamatan yang hilang melalui filter Kalman kadang-kadang ditafsirkan sebagai ekstrapolasi seri; ketika Kalman lebih halus digunakan, pengamatan yang hilang dikatakan diisi dengan interpolasi dalam seri yang diamati.