web-dev-qa-db-ja.com

遅延変数をLMモデルに追加しますか?

私は時系列でlmを使用していますが、これは実際には非常にうまく機能し、超高速です。

私のモデルは次のとおりだとしましょう:

_> formula <- y ~ x
_

これをトレーニングセットでトレーニングします。

_> train <- data.frame( x = seq(1,3), y = c(2,1,4) )
> model <- lm( formula, train )
_

...そして、新しいデータの予測を行うことができます:

_> test <- data.frame( x = seq(4,6) )
> test$y <- predict( model, newdata = test )
> test
  x        y
1 4 4.333333
2 5 5.333333
3 6 6.333333
_

これは非常にうまく機能し、非常に高速です。

遅延変数をモデルに追加したい。これで、元のトレーニングセットを増強することでこれを行うことができました。

_> train$y_1 <- c(0,train$y[1:nrow(train)-1])
> train
  x y y_1
1 1 2   0
2 2 1   2
3 3 4   1
_

数式を更新します。

_formula <- y ~ x * y_1
_

...そしてトレーニングはうまくいきます:

_> model <- lm( formula, train )
> # no errors here
_

ただし、問題は、テストセットにバッチ方式でy_1を設定する方法がないため、「予測」を使用する方法がないことです。

現在、他の多くの回帰については、poly(x,2)などのように式でそれらを表現する非常に便利な方法があり、これらは変更されていないトレーニングおよびテストデータを使用して直接機能します。

それで、predictを使用できるように、式で遅延変数を表現する方法があるかどうか疑問に思っていますか?理想的には:

_formula <- y ~ x * lag(y,-1)
model <- lm( formula, train )
test$y <- predict( model, newdata = test )
_

...トレーニングデータセットとテストデータセットを補強する必要はなく(正しいWordかどうかわからない)、predictを直接使用できるだけですか?

22
Hugh Perkins

たとえば、 dynlm パッケージは遅延演算子を提供します。より一般的には、計量経済学と時系列のタスクビューには、見るべきものがたくさんあります。

ここにその例の始まりがあります-1か月と12か月のラグ:

R>      data("UKDriverDeaths", package = "datasets")
R>      uk <- log10(UKDriverDeaths)
R>      dfm <- dynlm(uk ~ L(uk, 1) + L(uk, 12))
R>      dfm

Time series regression with "ts" data:
Start = 1970(1), End = 1984(12)

Call:
dynlm(formula = uk ~ L(uk, 1) + L(uk, 12))

Coefficients:
(Intercept)     L(uk, 1)    L(uk, 12)  
      0.183        0.431        0.511  

R> 
14

dynlmに関するDirkの提案に続いて、私は予測する方法を理解できませんでしたが、それを検索すると https://stats.stackexchange.com経由でdynパッケージに移動しました/ questions/6758/1-step-ahead-predictions-with-dynlm-r-package

その後、数時間の実験の後、予測を処理するために次の機能を思いつきました。途中でかなりの「落とし穴」がありました。たとえば、rbind時系列に見えない場合、predictの結果はstartとそのようなもので相殺されます。したがって、Dirkの答えを支持しましたが、この答えはパッケージに名前を付けるだけの場合に比べて大幅に追加されると感じています。

したがって、動作するソリューションは次のとおりです。

  • dynパッケージを使用します
  • 予測には次の方法を使用します

predictDynメソッド:

# pass in training data, test data,
# it will step through one by one
# need to give dependent var name, so that it can make this into a timeseries
predictDyn <- function( model, train, test, dependentvarname ) {
    Ntrain <- nrow(train)
    Ntest <- nrow(test)
    # can't rbind ts's apparently, so convert to numeric first
    train[,dependentvarname] <- as.numeric(train[,dependentvarname])
    test[,dependentvarname] <- as.numeric(test[,dependentvarname])
    testtraindata <- rbind( train, test )
    testtraindata[,dependentvarname] <- ts( as.numeric( testtraindata[,dependentvarname] ) )
    for( i in 1:Ntest ) {
       result <- predict(model,newdata=testtraindata,subset=1:(Ntrain+i-1))
       testtraindata[Ntrain+i,dependentvarname] <- result[Ntrain + i + 1 - start(result)][1]
    }
    return( testtraindata[(Ntrain+1):(Ntrain + Ntest),] )
}

使用例:

library("dyn")

# size of training and test data
N <- 6
predictN <- 10

# create training data, which we can get exact fit on, so we can check the results easily
traindata <- c(1,2)
for( i in 3:N ) { traindata[i] <- 0.5 + 1.3 * traindata[i-2] + 1.7 * traindata[i-1] }
train <- data.frame( y = ts( traindata ), foo = 1)

# create testing data, bunch of NAs
test <- data.frame( y = ts( rep(NA,predictN) ), foo = 1)

# fit a model
model <- dyn$lm( y ~ lag(y,-1) + lag(y,-2), train )
# look at the model, it's a perfect fit. Nice!
print(model)

test <- predictDyn( model, train, test, "y" )
print(test)

# Nice plot
plot(test$y, type='l')

出力:

> model

Call:
lm(formula = dyn(y ~ lag(y, -1) + lag(y, -2)), data = train)

Coefficients:
(Intercept)   lag(y, -1)   lag(y, -2)  
        0.5          1.7          1.3  

> test
             y foo
7     143.2054   1
8     325.6810   1
9     740.3247   1
10   1682.4373   1
11   3823.0656   1
12   8686.8801   1
13  19738.1816   1
14  44848.3528   1
15 101902.3358   1
16 231537.3296   1

編集:うーん、これはしかし非常に遅いです。 subsetのデータをデータセットの一定の数行に制限しても、予測ごとに約24ミリ秒かかります。または、私のタスクでは0.024*7*24*8*20*10/60/60 = 1.792 hours:-O

5
Hugh Perkins

ARIMA関数を試してください。 ARパラメーターは自己回帰用であり、yの遅れを意味します。 xreg =他のX変数を追加できます。 predict.ARIMAで予測を取得できます。

2
PL84

考えは次のとおりです。

新しいデータフレームを作成してみませんか?データフレームに必要なリグレッサを入力します。必要な変数のすべてのラグに対してL1、L2、...、Lpのような列を作成し、断面タイプの回帰の場合とまったく同じように関数を使用できます。

フィッティング関数と予測関数を呼び出すたびにデータを操作する必要はありませんが、データを一度変換すると、かなり高速になります。 EviewsとStataが遅れる演算子を提供することを知っています。それにはいくつかの便利さがあります。しかし、「lm」計算などのすべての機能が必要でない場合も非効率的です。実行する数十万の反復があり、予測、または予測と、BICやAICなどの情報基準の値だけが必要な場合は、計算を行わないことで「lm」に勝ることができます使用-関数にOLS推定量を記述するだけで、準備完了です。

0
Stéphane