如何用R拟合ARIMAX模型?


33

我有四个不同的每小时测量时间序列:

  1. 房屋内部的热量消耗
  2. 屋外温度
  3. 太阳辐射
  4. 风速

我希望能够预测房屋内部的热量消耗。每年和每天都有明显的季节性趋势。由于不同系列之间存在明显的相关性,因此我想使用ARIMAX模型拟合它们。可以使用包TSA中的arimax函数在R中完成。

我试图阅读有关此函数的文档,并阅读传递函数,但到目前为止,我的代码是:

regParams = ts.union(ts(dayy))
transferParams = ts.union(ts(temp))
model10 = arimax(heat,order=c(2,1,1),seasonal=list(order=c(0,1,1),period=24),xreg=regParams,xtransf=transferParams,transfer=list(c(1,1))
pred10 = predict(model10, newxreg=regParams)

给我: 在此处输入图片说明

黑线是实际测量的数据,绿线是我的比较模型。这不仅不是一个好的模型,而且显然有些错误。

我承认我对ARIMAX模型和传递函数的了解有限。在函数arimax()中(据我了解),xtransf是我要使用(使用传递函数)来预测我的主要时间序列的外生时间序列。但是xreg和xtransf到底有什么区别?

一般来说,我做错了什么?我希望能够获得比从lm(热〜临时辐射风*时间)获得的更好的拟合度。

编辑: 基于一些评论,我删除了transfer,并添加了xreg:

regParams = ts.union(ts(dayy), ts(temp), ts(time))
model10 = arimax(heat,order=c(2,1,1),seasonal=list(order=c(0,1,1),period=24),xreg=regParams)

其中dayy是“一年中的第几天”,而时间是一天中的小时。温度再次是外界温度。这给了我以下结果:

在此处输入图片说明

更好,但远不及我所期望的。

Answers:


34

使用ARIMA模型来建模具有2个季节性水平的系列会有些麻烦。正确执行此操作高度取决于正确设置。您是否考虑过简单的线性模型?与ARIMA模型相比,它们更快,更容易拟合,并且如果您针对不同的季节性水平使用虚拟变量,它们通常会非常准确。

  1. 我假设您有每小时的数据,因此请确保将TS对象的频率设置为24。
  2. 您可以使用虚拟变量对其他季节性水平进行建模。例如,您可能需要一组0/1虚拟变量来代表一年中的月份。
  3. xreg参数中包括虚拟变量以及任何协变量(例如温度)。
  4. 用R中的arima函数拟合​​模型。此函数可以通过使用xreg参数来处理ARMAX模型。
  5. 尝试使用预测包中的Arimaauto.arima函数。auto.arima很不错,因为它将自动为您的arima模型找到合适的参数。但是,将需要FOREVER永远适合您的数据集。
  6. 试试arima软件包中的tslm函数,对每个季节级别使用伪变量。这将比Arima模型快很多,甚至在您遇到的情况下效果更好。
  7. 如果4/5/6不起作用,则开始担心传递函数。您必须先爬网,然后才能行走。
  8. 如果您打算预测未来,则首先需要预测xreg变量。这对于季节性假人很容易,但是您必须考虑如何做出良好的天气预报。也许使用历史数据的中位数?

这是我将如何处理此示例:

#Setup a fake time series
set.seed(1)
library(lubridate)
index <- ISOdatetime(2010,1,1,0,0,0)+1:8759*60*60
month <- month(index)
hour <- hour(index)
usage <- 1000+10*rnorm(length(index))-25*(month-6)^2-(hour-12)^2
usage <- ts(usage,frequency=24)

#Create monthly dummies.  Add other xvars to this matrix
xreg <- model.matrix(~as.factor(month))[,2:12]
colnames(xreg) <- c('Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec')

#Fit a model
library(forecast)
model <- Arima(usage, order=c(0,0,0), seasonal=list(order=c(1,0,0), period=24), xreg=xreg)
plot(usage)
lines(fitted(model),col=2)

#Benchmark against other models
model2 <- tslm(usage~as.factor(month)+as.factor(hour))
model3 <- tslm(usage~as.factor(month))
model4 <- rep(mean(usage),length(usage))

#Compare the 4 models
library(plyr) #for rbind.fill
ACC <- rbind.fill(  data.frame(t(accuracy(model))),
                    data.frame(t(accuracy(model2))),
                    data.frame(t(accuracy(model3))),
                    data.frame(t(accuracy(model4,usage)))
                )
ACC <- round(ACC,2)
ACC <- cbind(Type=c('Arima','LM1','Monthly Mean','Mean'),ACC)
ACC[order(ACC$MAE),]

什么是fit()函数。如果使用它,我得到的结果将比使用预报(model10,newxreg = regParams)更好。
utdiscant

@utdiscant:predict()用于预测,同时fitted()返回适合历史时期的模型。如果您需要更多具体的帮助,则应发布带有一些代码的可复制示例。
扎克(Zach)

@utdiscant:另外,如果您将dayy用作xreg,则存在过拟合的风险,因为每天只有24个观测值。如果使用一年中的月份,则可能会获得更好的预测结果。
扎克(Zach)

@utdiscant:此外,基于时间的xreg必须是虚拟变量。现在进行建模的方式是,您希望heat随着一天中的小时数线性增加,然后在小时数返回1时又向下跳。如果您使用虚拟变量,则一天中的每一小时都会发挥作用。运行示例代码,并仔细注意如何构造xreg对象。
Zach

statsforecast软件包中ARIMA函数的缺点之一是它们不适合探测器传递函数。该stats::arima函数的文档说明以下内容:如果包括xreg项,则线性回归(如果include.mean为true且没有差异,则为常数项)与ARMA模型拟合为误差项。因此,如果您实际上需要适合传递函数,则似乎该TSA::arimax函数是使用的方法R
Christoffer,

8

一段时间以来,我一直在使用R进行负载预测,我建议您使用forecastpackage及其宝贵的功能(例如auto.arima)。

您可以使用以下命令构建ARIMA模型:

model = arima(y, order, xreg = exogenous_data)

y您的预测(我想dayy),order模型的顺序(考虑季节)以及exogenous_data温度,太阳辐射等有关。此功能auto.arima可帮助您找到最佳的模型顺序。您可以在此处找到有关`forecast'软件包的简短教程。


可以预测的是热量(房屋的热量消耗)。
utdiscant

3

我个人不了解传递函数,但是我认为您理解了xtransfxreg逆转了。至少在R的基础上,arimaxreg包含您的外生变量。我的印象是,传递函数描述的(滞后数据影响未来值)而不是什么

我会尝试使用xreg您的外生变量,arima如果arimax需要传递函数,则可能会使用。问题在于您的模型是每日的,但是您的数据具有每日和每年的季节性,因此我现在不确定第一个差异(order=(*, 1, *))是否可以解决。(从仅考虑每日季节性的模型中,您当然不会获得神奇的全年预测。)

PS time您使用的是lm什么?字面时钟时间还是一个向上观察的数字?我认为您可以通过使用混合效果模型(lmerlme4包装中)获得一些好处,尽管我还没有弄清楚这样做是否正确说明了时间序列中将发生的自相关。如果不加以考虑,但lm事实并非如此,您可能会很有趣,但是您对预测的精确度的看法将过于乐观。


我既有测量的小时数,也有测量的“一年中的某天”。
utdiscant
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.