auto.arimaを使用して欠損値を補完する方法


12

多くの欠損値のある動物園シリーズがあります。auto.arimaこれらの欠損値を推定できると私は読みましたか?誰でも私にそれを行う方法を教えることができますか?どうもありがとう!

これは私が試したものですが、成功しませんでした:

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

javlacalleへの追加と以下の私の回答として:その間、これらをimputeTSパッケージに実装しました。関数はna.kalmanと呼ばれ、ARIMAモデルの状態空間形式でカルマン平滑化を行います
stats0007

回答:


25

まず、forecastはサンプル外の予測を計算しますが、サンプル内の観測に関心があることに注意してください。

カルマンフィルターは欠損値を処理します。したがって、forecast::auto.arimaまたはによって返された出力からARIMAモデルの状態空間形式を取得して、stats::arimaそれをに渡すことができKalmanRunます。

編集 (stats0007による回答に基づいてコードを修正)

以前のバージョンでは、観測された系列に関連するフィルター処理された状態の列を取得しましたが、行列全体を使用し、観測方程式の対応する行列演算ます。(コメントについては@ stats0007に感謝します。)以下でコードを更新し、それに応じてプロットします。yt=Zαt

私はのts代わりにオブジェクトをサンプルシリーズとして使用していますzooが、同じである必要があります。

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

結果をプロットできます(サンプル全体の観測値が欠落しているシリーズ全体および1年全体)。

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

元の系列のプロットと欠落した観測値に帰属する値

カルマンフィルターの代わりにカルマンスムーザーを使用して同じ例を繰り返すことができます。変更する必要があるのは次の行だけです。

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

カルマンフィルターを使用して欠落している観測値を処理すると、系列の外挿として解釈される場合があります。カルマンスムーザーが使用されている場合、欠落している観測値は、観測された系列の内挿によって埋められると言います。


こんにちはJavlacalle様、ご協力ありがとうございます。時系列に何らかの条件があるかどうかを尋ねてもよいですか、またはこれが当てはまる可能性がありますか?これらのコマンドラインについて少し説明してもらえますか?tmp < model
-which

makeARIMA状態空間形式の行列がどのように定義されているかをもう一度確認しましたid。取得した列は正しいと言えます。観測方程式のベクトルは、で定義されるmakeARIMAような:Z <- c(1, rep.int(0, r - 1L), Delta)ここで、Delta差分フィルタの係数を含むベクトルです。差分フィルターがない場合(つまり、ARMAモデルlength(tmp)==1)、id1にする必要があります。それ以外の場合、最初の列は差分系列に関連Zし、値1をとる次の要素は(関連するインデックス)に関連します。yt1
javlacalle 14年

1
@ user3730957インデックスを使用してこの問題を解決するため、回答を更新しました。
javlacalle

2

ここに私の解決策があります:

# 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、非常に興味深い!

私はあなたの解決策に2つの質問があります、あなたが私を助けることができることを願っています:

  1. なぜKalmanSmoothの代わりにKalmanRunを使用するのですか?KalmanRunは外挿と見なされますが、スムーズは推定です。

  2. 私もあなたのid部分を取得しません。.Zのすべてのコンポーネントを使用しないのはなぜですか?たとえば、.Zは1、0、0、0、0、1、-1-> 7の値を示します。これは、.smooth(KalmanRun状態の場合)が7列を提供することを意味します。私が理解しているように、1または-1のすべての列がモデルに入ります。

    AirPassで行番号5が欠落しているとしましょう。次に、次のように行5の合計を取ります。列1から値を追加し(Zが1を与えたため)、列2-4を追加しません(Zが0と言うため)、列5を追加して、列7の負の値を追加します(Zが-1と言うため)

    私の解決策は間違っていますか?それともどちらも大丈夫ですか?さらに説明してもらえますか?


自分の回答内ではなく、@ Javlacalleの投稿へのコメントとして、回答の2番目の部分を投稿することをお勧めします。
Patrick Coulombe

試してみました...しかし、コメントするには50の評判が必要だと言っています
stats0007
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.