Cách sử dụng auto.arima để tính các giá trị còn thiếu


12

Tôi có một loạt sở thú với nhiều giá trị còn thiếu. Tôi đọc auto.arimacó thể áp đặt những giá trị còn thiếu này? Bất cứ ai có thể dạy tôi làm thế nào để làm điều đó? cảm ơn rất nhiều!

Đây là những gì tôi đã cố gắng, nhưng không thành công:

fit <- auto.arima(tsx)
plot(forecast(fit))

Là một bổ sung cho javlacalle và câu trả lời của tôi dưới đây: Tôi đã triển khai những điều này trong khi đó trong gói imputeTS. Hàm này được gọi là na.kalman và làm Kalman làm mịn trên dạng không gian trạng thái của mô hình ARIMA
thống kê0007

Câu trả lời:


25

Trước tiên, hãy lưu ý rằng forecasttính toán các dự đoán ngoài mẫu nhưng bạn quan tâm đến các quan sát trong mẫu.

Bộ lọc Kalman xử lý các giá trị bị thiếu. Do đó, bạn có thể lấy dạng không gian trạng thái của mô hình ARIMA từ đầu ra được trả về bởi forecast::auto.arimahoặc stats::arimavà chuyển nó sang KalmanRun.

Chỉnh sửa (sửa mã dựa trên câu trả lời của stats0007)

yt= =Zαt

Tôi sử dụng một tsđối tượng như một chuỗi mẫu thay vì zoo, nhưng nó phải giống nhau:

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

Bạn có thể vẽ kết quả (cho toàn bộ chuỗi và cho cả năm với các quan sát bị thiếu ở giữa mẫu):

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))

cốt truyện của loạt ban đầu và các giá trị được đưa ra cho các quan sát bị thiếu

Bạn có thể lặp lại ví dụ tương tự bằng cách sử dụng bộ lọc Kalman mượt mà thay vì bộ lọc Kalman. Tất cả bạn cần thay đổi là những dòng này:

kr <- KalmanSmooth(x, fit$model)
y[i] <- kr$smooth[i,]

Xử lý các quan sát bị thiếu bằng bộ lọc Kalman đôi khi được hiểu là ngoại suy của chuỗi; khi Kalman mượt mà hơn được sử dụng, các quan sát bị thiếu được cho là được lấp đầy bằng phép nội suy trong chuỗi quan sát.


modetôi

makeARIMAidmakeARIMAZ <- c(1, rep.int(0, r - 1L), Delta)Deltalength(tmp)==1idZyt-1

1
@ user3730957 Tôi đã cập nhật câu trả lời của mình để khắc phục vấn đề này với việc lập chỉ mục.
javlacalle

2

Đây sẽ là giải pháp của tôi:

# Take AirPassengers as example
data <- AirPassengers

# Set missing values
data[c(44,45,88,90,111,122,129,130,135,136)] <- NA


missindx <- is.na(data)

arimaModel <- auto.arima(data)
model <- arimaModel$model

#Kalman smoothing
kal <- KalmanSmooth(data, model, nit )
erg <- kal$smooth  

for ( i in 1:length(model$Z)) {
       erg[,i] = erg[,i] * model$Z[i]
}
karima <-rowSums(erg)

for (i in 1:length(data)) {
  if (is.na(data[i])) {
    data[i] <- karima[i]
  }
}
#Original TimeSeries with imputed values
print(data)

@ Javlacalle:

Thx cho bài viết của bạn, rất thú vị!

Tôi có hai câu hỏi cho giải pháp của bạn, hy vọng bạn có thể giúp tôi:

  1. Tại sao bạn sử dụng KalmanRun thay vì KalmanSmooth? Tôi đọc KalmanRun được coi là ngoại suy, trong khi trơn tru sẽ là ước tính.

  2. Tôi cũng không nhận được phần id của bạn. Tại sao bạn không sử dụng tất cả các thành phần trong .Z? Ý tôi là ví dụ .Z cho các giá trị 1, 0,0,0,0,1, -1 -> 7. Điều này có nghĩa là .smooth (trong trường hợp của bạn cho các tiểu bang KalmanRun) cho tôi 7 cột. Theo tôi hiểu các cột alle là 1 hoặc -1 đi vào mô hình.

    Giả sử hàng số 5 bị thiếu trong AirPass. Sau đó, tôi sẽ lấy tổng của hàng 5 như thế này: Tôi sẽ thêm giá trị từ cột 1 (vì Z đã cho 1), tôi sẽ không thêm cột 2-4 (vì Z nói 0), tôi sẽ thêm cột 5 và tôi sẽ thêm thêm giá trị âm của cột 7 (vì Z nói -1)

    Là giải pháp của tôi sai? Hay cả hai đều ổn? Có lẽ bạn có thể giải thích cho tôi thêm?


Tôi khuyên bạn nên đăng phần thứ hai trong câu trả lời của bạn dưới dạng nhận xét cho bài đăng của @ Javlacalle thay vì trong câu trả lời của riêng bạn.
Patrick Coulombe

đã cố gắng ... nhưng nó nói rằng tôi phải có 50 danh tiếng để bình luận
thống kê0007
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.