使用 lm 和 lag 在 R 中预测时间序列回归

机器算法验证 r 流明
2022-03-24 02:52:42

我想在 R 中使用线性模型进行预测。我拥有的模型的形式是lm(y~ lag(x))看起来我应该能够使用 predict 函数进行预测,但这并不能展望未来。

这是我在 R 中使用的滞后函数。

lag1 = function (x) c(NA, x[1:(length(x)-1)])

这个滞后函数在数据的开头添加了一个 NA,将所有内容向下移动,并切断最后一次观察。

我最感兴趣的是对数据最后一行的预测。这行数据似乎被拟合和预测函数忽略了。

我发现的最佳解决方法是将每个模型系数乘以我的每个因变量,然后为每个预测加起来。当我建立这个方程时,此时没有任何因变量滞后。这样做的问题是,每次我更改模型公式时,都必须更改变量的名称以匹配新公式。似乎应该有一个更直观的解决方案。

1个回答

使用滞后进行估计并使用模型进行预测是基础 R 中的一个痛点。下面是示例:

set.seed(1)
y<-ts(rnorm(10))
x<-ts(rnorm(10))
lm(y~x)

Call:
lm(formula = y ~ x)

Coefficients:
(Intercept)            x  
     0.2006      -0.2749  

>    lm(y~lag(x))

Call:
lm(formula = y ~ lag(x))

Coefficients:
(Intercept)       lag(x)  
     0.2006      -0.2749  

请注意,在这两种情况下,结果是相同的。发生这种情况是因为默认滞后函数的一些特殊行为。比较xlag(x)

 x
Time Series:
Start = 1 
End = 10 
Frequency = 1 
 [1]  1.51178117  0.38984324 -0.62124058 -2.21469989  1.12493092 -0.04493361 -0.01619026  0.94383621  0.82122120
[10]  0.59390132
> lag(x)
Time Series:
Start = 0 
End = 9 
Frequency = 1 
 [1]  1.51178117  0.38984324 -0.62124058 -2.21469989  1.12493092 -0.04493361 -0.01619026  0.94383621  0.82122120
[10]  0.59390132

如您所见,数据是相同的,只是属性不同,在这种情况下是时间。因此 lm 看到相同的数据,因为它忽略了属性。有几种方法可以解决这种行为。这里有几个。

首先,您可以将数据转换为滞后行为为“标准”的时间序列格式。其中一种格式xts来自 package xts

yy<-xts(y,as.Date(1:10))
xx<-xts(x,as.Date(1:10))
lm(yy~xx)

Call:
lm(formula = yy ~ lag(xx))

Coefficients:
(Intercept)      lag(xx)  
     0.2754      -0.2798 

现在看到系数不同了,因为lag现在正确地移动了数据:

lag(xx)
                  [,1]
1970-01-02          NA
1970-01-03  1.51178117
1970-01-04  0.38984324
1970-01-05 -0.62124058
1970-01-06 -2.21469989
1970-01-07  1.12493092
1970-01-08 -0.04493361
1970-01-09 -0.01619026
1970-01-10  0.94383621
1970-01-11  0.82122120

dynlm另一种方法是使用包dynlm中的函数来估计回归

dynlm(y~L(x))

Time series regression with "ts" data:
Start = 2, End = 10

Call:
dynlm(formula = y ~ L(x))

Coefficients:
(Intercept)         L(x)  
     0.2754      -0.2798  

这涵盖了估计。现在预测更棘手。要获得拟合值,您可以简单地使用predict函数:

predict(dynlm(y ~ L(x)))
          2           3           4           5           6           7           8           9          10 
-0.14757748  0.16632219  0.44920672  0.89503027 -0.03934318  0.28796556  0.27992365  0.01132412  0.04562977 
predict(lm(yy ~ lag(xx)))
          2           3           4           5           6           7           8           9          10 
-0.14757748  0.16632219  0.44920672  0.89503027 -0.03934318  0.28796556  0.27992365  0.01132412  0.04562977 

对未来进行预测虽然存在问题。函数的默认行为predict是期望newdata参数。但是在这种情况下,对于提前一步的预测,不需要新的数据。所以标准predict功能在这种情况下不起作用。我很想看到这个问题的通用解决方案,但据我所知,不同的包提供了不同的方法来获取此类预测,如果您不想自己编写函数,则需要将模型转换为所需的形式来自特定包的特定预测功能。而且您需要非常了解该软件包。

其中之一是midasr(我是其中的开发人员)。此类模型的提前预测将通过以下方式实施:

midas_u(y~mls(x,1,1))

Call:
lm(formula = y ~ mls(x, 1, 1), data = ee)

Coefficients:
 (Intercept)  mls(x, 1, 1)  
      0.2754       -0.2798  

forecast(midas_u(y~mls(x,1,1)),newdata=list(x=NA))
[1] 0.1092301

midasr适用于混合频率数据。该函数mls有 3 个参数,数据、滞后数和频率比。在这种情况下,频率是相同的,所以第三个参数是 1。在这种情况下,函数lagxts对象函数完全一样。为了预测,有必要提供新数据。由于我们不知道,我们提供了在这种情况下有效的 NA,因为在这种情况下提前一步预测只需要我们已经知道的数据。

的最后一个值为x0.59390132,所以可以直接检查结果是否正确

> 0.59390132*(-0.2798)  +0.2754
[1] 0.1092264

答案正确到小数点后 4 位,因为我使用了 4 位精度的系数。