我在时间序列中使用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
然而,问题在于无法使用'predict',因为无法以批处理方式在测试集中填充y_1。
现在,对于许多其他回归事物,有很方便的方法在公式中表达它们,例如poly(x,2)
等等,这些方法直接使用未经修改的训练和测试数据。
所以,我想知道在公式中是否有某种表达滞后变量的方法,以便可以使用predict
?理想的情况是:
formula <- y ~ x * lag(y,-1)
model <- lm( formula, train )
test$y <- predict( model, newdata = test )
...无需增加(不确定这是否是正确的词)训练和测试数据集,只是能够直接使用predict
?
答案 0 :(得分:14)
看看例如dynlm包,它为您提供滞后运算符。更一般地说,计量经济学和时间序列的任务视图将有更多的东西供您查看。
以下是其示例的开头 - 一个月和十二个月的滞后:
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>
答案 1 :(得分:5)
根据Dirk对dynlm
的建议,我无法弄清楚如何预测,但通过https://stats.stackexchange.com/questions/6758/1-step-ahead-predictions-with-dynlm-r-package
dyn
包裹
然后经过几个小时的实验,我想出了以下函数来处理预测。路上有很多'问题',例如你似乎不能rbind
时间序列,预测的结果被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
答案 2 :(得分:2)
尝试ARIMA功能。 AR参数用于自动回归,这意味着y滞后。 xreg =允许您添加其他X变量。您可以使用predict.ARIMA获得预测。
答案 3 :(得分:0)
这是一个想法:
为什么不创建新的数据框?使用您需要的回归量填充数据框。对于你想要的任何变量的所有滞后,你可以有像L1,L2,...,Lp这样的列,然后,你可以像使用横截面类型的回归一样使用你的函数。
因为每次调用拟合和预测函数时都不必对数据进行操作,但是将数据转换一次,速度会快得多。我知道Eviews和Stata提供了滞后的运营商。确实有一些方便。但是如果你不需要像&#39; lm&#39;那样的所有功能,它也是低效的。计算。如果您需要执行几十万次迭代,并且您只需要预测,或预测以及BIC或AIC等信息标准的价值,那么您可以击败&#39; lm&#39;通过避免进行你不会使用的计算来提高速度 - 只需在函数中编写一个OLS估算器,你就可以了。