簡體   English   中英

R 中的滾動 AR 回歸

[英]Rolling AR regressions in R

我正在管理具有 348 個觀測值的純月度時間序列數據。

這是可重現的樣本數據:

library(dplyr)
set.seed(123)

Y <- cumsum(rnorm(48))
date <- as.Date(c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01", 
                  "2012-05-01","2012-06-01", "2012-07-01", "2012-08-01",
                  "2012-09-01","2012-10-01","2012-11-01", "2012-12-01",
                  "2013-01-01", "2013-02-01","2013-03-01", "2013-04-01", 
                  "2013-05-01","2013-06-01", "2013-07-01", "2013-08-01",
                  "2013-09-01","2013-10-01","2013-11-01", "2013-12-01",
                  "2014-01-01", "2014-02-01","2014-03-01", "2014-04-01", 
                  "2014-05-01","2014-06-01", "2014-07-01", "2014-08-01",
                  "2014-09-01","2014-10-01","2014-11-01", "2014-12-01",
                  "2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", 
                  "2015-05-01","2015-06-01",  "2015-07-01", "2015-08-01",
                  "2015-09-01","2015-10-01","2015-11-01", "2015-12-01"))

data<-data.frame(date,Y)

我正在復制一篇論文並計算“震驚”。 引用的程序如下:

“這些系列中的每一個中的沖擊都是通過 AR(2) 模型在以第 n 個月結束的 10 個月滾動窗口內計算的。第 n+1 個月的沖擊用 dYn+1 表示是該系列實際值之間的差異及其使用前 10 個月估計的斜率系數的預測值。因此,我們的方法是前瞻性的,提供樣本外預測誤差。”

根據原作者的說法,帶有趨勢項的 AR(2) 模型如下:

Yt = a0 + a1*Yt-1 + a2*Yt-2 + a3*Tt+ residualt
where Tt is the serial number of the observation, to account for a time trend in these series.

如果我的目標是使用前 10 個 obs 計算第 11 個的平均值,我可以簡單地調用以下代碼:

Mean= slide_index_dbl(Y, date, mean, .before = months(10), .after = months(-1), .complete = T)

但是,在這種情況下,目標是使用所有之前的 10 個 obs 運行 AR 模型,並使用此估計模型預測第 11 個,最終輸出是第 11 個的實際值減去預測值。 簡單來說,我需要構造一個函數來實現這個目標,而不是在前面的例子中使用“mean”函數。

一旦我完成這個函數(我們稱之為 AR_2),我們就可以在滑塊內部調用它。

library(slider)

data1<-data%>%
  mutate(Shock= slide_index_dbl(Y, date, AR_2, .before = months(10), .after = months(-1), .complete = T))

   Date       Y     N  Predict    Shock
2012-01-01   0.15   1    0.2     -0.005
2012-02-01   0.4    2    0.33      0.07
2012-03-01   0.39   3    0.44     -0.05
... 
2012-10-01   1.85   10   2.1      -0.25
2012-11-01   1.7    11   1.5       0.2   
2012-12-01   3.46   12   4.1      -0.65

讓我使用我制作的上述示例數據來說明我的問題。 最終輸出是 Shock,它是 Y(實際數據)和 Predicted Y 之間的差值。話雖如此,問題是如何得到 Predicted Y。在我們預測 Y 之前,我們需要先通過輸入先前的數據來訓練 AR 模型10 個月的數據。 一旦你得到這個模型,你就可以用這個模型預測第 11 個 obs,那將是預測的 Y。最后的嘗試是計算它與實際 Y 之間的差異,這稱為沖擊。

數值示例如下:為了獲得 2012-11-01 的輸出 0.074,我需要使用從 2012-01-01 到 2012-10-01 的所有前 10 個月的數據訓練一個 AR(2) 模型,即Y 為 0.15 到 1.85,N 為 1 到 10。一旦我訓練了這個模型,我就用它來預測 2012 年 11 月 1 日的新值 (0.2)。 最終輸出“Shock”是 2012-11-01 的實際觀測值與預測觀測值之間的差值 (0.15-0.2=0.05)。

同樣,為了獲得 2012-12-01 的輸出 0.08,我需要使用從 2012-02-01 到 2012-11-01 的所有前 10 個月的數據訓練一個 AR(2) 模型,即從 0.4 到 1.7對於 Y 和 2 到 11,對於 N。一旦我訓練了這個模型,我就用它來預測 2012 年 12 月 1 日的新值 (4.1)。 最終輸出“Shock”是 2012-12-01 的實際觀測值與預測觀測值之間的差值 (3.46-4.1=-0.65)。

我不知道如何編寫這樣的函數(AR_2)並在 slide_index_dbl 中調用它。 請記住 AR_2 中有一個趨勢項 a3*Tt,我不知道如何建模。

以下是我嘗試過的。 我使用 lm 來實現 AR moel 而不是 arima。 這是因為我不知道如何使用 arima 來預測新值。 如果有人熟悉 arima 或 Arima 功能,請使用它。

Intercept_extract_lm<-function(x){
  N<-rep(1:10)
  model<-lm(x~ lag(x,1)+ lag(x, 2)+N)
  coef(model)["(Intercept)"]
}

Log_1_extract_lm<-function(x){
  N<-rep(1:10)
  model<-lm(x~ lag(x,1)+ lag(x, 2)+N)
  coef(model)["Lag_1"]
}

Log_2_extract_lm<-function(x){
  N<-rep(1:10)
  model<-lm(x~ lag(x,1)+ lag(x, 2)+N)
  coef(model)["Lag_2"]
}


drift_extract_lm<-function(x){
  N<-rep(1:10)
  model<-lm(x~ lag(x,1)+ lag(x, 2)+N)
  coef(model)["N"]
}

data1<-data%>%
  mutate(Lag_1=lag(Y,1),Lag_2=lag(Y,2),N=1:n(),
         a1=slide_index_dbl(Y, Date, Log_1_extract_lm, .before = months(10), .after = months(-1), .complete = T),
         a2=slide_index_dbl(Y, Log_2_extract_lm, .before = months(10), .after = months(-1), .complete = T),
         drift=slide_index_dbl(Y, Date, drift_extract_lm, .before = months(10), .after = months(-1), .complete = T),
         Intercept = slide_index_dbl(Y, Date, Intercept_extract_lm, .before = months(10), .after = months(-1), .complete = T),
         Predict=Intercept+a1*Lag_1+a2*Lag_2+drift,
         Shock=Y-Predict)

我知道我的代碼中最大的問題是它只能在滑塊中使用一個輸入參數,但我在定義的所有自定義函數中使用了四個(Y 和 lag_1 以及 lag_2 和 N)。 與前面的例子不同,我們只計算一個變量的滾動平均值,在這種情況下,為了運行這樣的回歸,我們需要在每個滾動窗口中有四個變量,但滑塊只有一個變量輸入。 即使我們編輯“提取”函數將四個變量減少到兩個(lag_1和lag_2可以寫成lag(Y,1)和lag(Y,2),我們仍然有Y和N兩個變量輸入)

至於趨勢項,根據我的理解,例如,對於2012-11-01,為了運行回歸,我需要前10分鍾的N,即1,2,3....10,即序列號的 obs。 對於 2012-12-01,它還應該包括來自 1,2,3...10 的 N,但是,根據我的代碼,它是 2,3,4...11。 但是添加常數 1 (2,3...11 vs 1,2,...10) 不會影響回歸系數,對吧? 老實說,我不確定這種情況下的趨勢術語,如果您了解原始作者,請隨時更改它。

你可以這樣做。 您的滯后 2 [A(2) 模型] 問題將由order = c(2,0,0) ,您不必明確這樣做。 arima()函數與predict()結合使用。

library(tidyverse)
set.seed(123)
Y <- cumsum(rnorm(48))
date <- as.Date(c("2012-01-01", "2012-02-01", "2012-03-01", "2012-04-01", 
                  "2012-05-01","2012-06-01", "2012-07-01", "2012-08-01",
                  "2012-09-01","2012-10-01","2012-11-01", "2012-12-01",
                  "2013-01-01", "2013-02-01","2013-03-01", "2013-04-01", 
                  "2013-05-01","2013-06-01", "2013-07-01", "2013-08-01",
                  "2013-09-01","2013-10-01","2013-11-01", "2013-12-01",
                  "2014-01-01", "2014-02-01","2014-03-01", "2014-04-01", 
                  "2014-05-01","2014-06-01", "2014-07-01", "2014-08-01",
                  "2014-09-01","2014-10-01","2014-11-01", "2014-12-01",
                  "2015-01-01", "2015-02-01", "2015-03-01", "2015-04-01", 
                  "2015-05-01","2015-06-01",  "2015-07-01", "2015-08-01",
                  "2015-09-01","2015-10-01","2015-11-01", "2015-12-01"))

data <- data.frame(date,Y)

library(lubridate, warn.conflicts = F)
library(slider)

data %>% 
  mutate(pred_roll_10 = slide_index_dbl(Y, .i = date, 
                                        ~ predict(arima(.x, c(2,0,0), method = 'ML'),1)$pred[1], 
                                        .before = months(10),
                                        .after = months(-1),
                                        .complete = T),
         shock = Y - pred_roll_10)
#> Warning in log(s2): NaNs produced

#> Warning in log(s2): NaNs produced

#> Warning in log(s2): NaNs produced

#> Warning in log(s2): NaNs produced
#>          date          Y pred_roll_10        shock
#> 1  2012-01-01 -0.5604756           NA           NA
#> 2  2012-02-01 -0.7906531           NA           NA
#> 3  2012-03-01  0.7680552           NA           NA
#> 4  2012-04-01  0.8385636           NA           NA
#> 5  2012-05-01  0.9678513           NA           NA
#> 6  2012-06-01  2.6829163           NA           NA
#> 7  2012-07-01  3.1438325           NA           NA
#> 8  2012-08-01  1.8787713           NA           NA
#> 9  2012-09-01  1.1919184           NA           NA
#> 10 2012-10-01  0.7462564           NA           NA
#> 11 2012-11-01  1.9703382    0.6951079  1.275230339
#> 12 2012-12-01  2.3301521    2.0524671  0.277684986
#> 13 2013-01-01  2.7309235    1.9333295  0.797594017
#> 14 2013-02-01  2.8416062    2.0486834  0.792922863
#> 15 2013-03-01  2.2857651    1.9959595  0.289805588
#> 16 2013-04-01  4.0726782    1.7514948  2.321183420
#> 17 2013-05-01  4.5705287    3.6469980  0.923530738
#> 18 2013-06-01  2.6039116    4.0585260 -1.454614411
#> 19 2013-07-01  3.3052675    1.6480334  1.657234048
#> 20 2013-08-01  2.8324760    2.9543635 -0.121887466
#> 21 2013-09-01  1.7646523    2.8739943 -1.109341911
#> 22 2013-10-01  1.5466774    2.7845341 -1.237856702
#> 23 2013-11-01  0.5206730    2.5894221 -2.068749114
#> 24 2013-12-01 -0.2082182    1.3652172 -1.573435497
#> 25 2014-01-01 -0.8332575    0.3654956 -1.198753080
#> 26 2014-02-01 -2.5199508   -0.5625776 -1.957373251
#> 27 2014-03-01 -1.6821638   -2.6388755  0.956711703
#> 28 2014-04-01 -1.5287907   -0.7131115 -0.815679154
#> 29 2014-05-01 -2.6669276   -1.2140023 -1.452925253
#> 30 2014-06-01 -1.4131127   -2.6421098  1.228997135
#> 31 2014-07-01 -0.9866485   -1.0140132  0.027364706
#> 32 2014-08-01 -1.2817199   -0.8209904 -0.460729511
#> 33 2014-09-01 -0.3865943   -1.2655968  0.879002504
#> 34 2014-10-01  0.4915392   -1.1977841  1.689323273
#> 35 2014-11-01  1.3131203   -0.4463373  1.759457622
#> 36 2014-12-01  2.0017605    0.9931931  1.008567426
#> 37 2015-01-01  2.5556782    1.7819117  0.773766509
#> 38 2015-02-01  2.4937665    2.3699293  0.123837184
#> 39 2015-03-01  2.1878038    2.1804620  0.007341787
#> 40 2015-04-01  1.8073328    1.5452418  0.262091026
#> 41 2015-05-01  1.1126258    1.2644697 -0.151843849
#> 42 2015-06-01  0.9047086    0.2974574  0.607251157
#> 43 2015-07-01 -0.3606878    0.7761950 -1.136882824
#> 44 2015-08-01  1.8082682   -1.1719233  2.980191448
#> 45 2015-09-01  3.0162302    1.9584189  1.057811310
#> 46 2015-10-01  1.8931216    2.5356767 -0.642555104
#> 47 2015-11-01  1.4902368    1.2115509  0.278685838
#> 48 2015-12-01  1.0235814    1.4319100 -0.408328595

reprex 包( v2.0.0 ) 於 2021 年 7 月 8 日創建

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM