如何用 R 拟合 ARIMAX 模型?

机器算法验证 时间序列 造型 有马
2022-01-25 19:37:26

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

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

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

我试图阅读有关此功能的文档,并阅读有关传输功能的信息,但到目前为止,我的代码:

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(热〜温度辐射风*时间)获得的更合适。

编辑: 根据一些评论,我删除了转移,并添加了 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 是“一年中的第几天”,time 是一天中的小时。温度又是外面的温度。这给了我以下结果:

在此处输入图像描述

哪个更好,但与我预期的不太一样。

3个回答

使用 ARIMA 模型对具有 2 个季节性水平的序列进行建模会有些麻烦。做到这一点在很大程度上取决于正确设置。您是否考虑过简单的线性模型?它们比 ARIMA 模型更快、更容易拟合,如果您对不同的季节性水平使用虚拟变量,它们通常非常准确。

  1. 我假设您有每小时数据,因此请确保您的 TS 对象设置为频率为 24。
  2. 您可以使用虚拟变量对其他季节性水平进行建模。例如,您可能需要一组代表一年中月份的 0/1 虚拟变量。
  3. 在参数中包含虚拟变量xreg以及任何协变量(如温度)。
  4. 用基础 R 中的 arima 函数拟合模型。该函数可以通过使用参数来处理 ARMAX 模型xreg
  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),]

我一直在使用 R 进行负载预测,我可以建议您使用forecast包及其宝贵的功能(如auto.arima)。

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

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

使用y您的预测变量(我想dayy)、order模型的顺序(考虑季节性)以及exogenous_data温度、太阳辐射等。该功能auto.arima可帮助您找到最佳模型顺序。您可以在此处找到有关“预测”包的简短教程

我个人不了解传递函数,但我认为你得到了xtransfxreg反转。至少在 R 的基础arima中,它xreg包含您的外生变量。我的印象是,传递函数描述的是(滞后数据如何影响未来值)而不是什么

我会尝试使用xreg你的外生变量,也许使用arimaifarimax需要传递函数。问题是您的模型是每日的,但您的数据具有每日和每年的季节性,我现在不确定第一个差异(the order=(*, 1, *))是否会解决这个问题。(你当然不会从只考虑每日季节性的模型中得到神奇的全年预测。)

PStime你用的是lm什么?文字时钟时间还是 1-up 观察数?我认为您可以通过使用混合效应模型(lmerlme4包中)来获得一些东西,尽管我还没有弄清楚这样做是否正确解释了时间序列中将发生的自相关。如果不考虑,但lm不考虑,您可能会得到一个有趣的拟合,但是您对预测的精确程度的概念将过于乐观。