一天中不同时间段的不同型号

数据挖掘 预测建模 时间序列 回归 预报
2022-02-15 06:55:26

我有一个月中几天的每小时温度和功耗数据。这种模式在这样的日子里几乎是相似的: 在此处输入图像描述

使用这些数据,我想预测未来一天的使用情况。我有特点:1)一天中的小时2)温度;和响应变量,功率。看数据,我相信我应该拟合三个独立的模型而不是一个模型

  1. 从午夜到上午 10 点的数据的第一个模型,因为在此期间使用量几乎保持不变,并且温度变化不大
  2. 从上午 11 点到下午 6 点的数据的第二个模型。这部分急剧增加,然后几乎恒定使用
  3. 从晚上 7 点到午夜的数据的第三个模型。这部分显示功率不断下降

为了遵循这种直觉,我相应地使用了三个模型,然后将这些模型的预测结合起来,输出未来一天的 24 个数字序列。这些模型中的每一个的公式是: lm(power ~ time_hour + temperature, data = xxx),但是每个模型都使用与一天中特定时间段相对应的数据进行训练。

除了手动划分数据并使用三个单独的模型之外,还有其他现有技术可以照顾我们的直觉并且不需要手动划分数据或创建单独的模型。

在我的搜索过程中,我发现我可以使用 GAM(广义加法模型)并且我想出了以下公式

library(splines) 
lm(power ~ ns(time_hour, knots =(9, 18)) + temperture, data = xxx)

使用上面的公式,我认为我在上午 9 点和下午 6 点打结。对?我不知道我应该如何在这些特定时间准确地执行温度特征的节点,以便节点temperature和节点time_hour同步。


上面的图是使用以下数据绘制的:

dframe <- structure(list(time_hour = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), temperature = c(22.5, 
24, 23.5, 20.5, 22.5, 22.5, 19.5, 23.5, 23, 20.5, 26.5, 28.5, 
30, 32, 33.5, 33, 30.5, 30, 29.5, 29, 28, 27, 28, 28.5), power = c(97.04319, 
95.7225, 88.59191, 88.34882, 90.17179, 88.82062, 87.73833, 89.36342, 
85.31775, 91.1292, 116.79035, 149.58614, 172.32438, 171.27931, 
159.53858, 162.03544, 170.78468, 164.0275, 155.86717, 135.77197, 
133.01235, 116.29253, 100.87483, 97.84942)), .Names = c("time_hour", 
"temperature", "power"), row.names = c(NA, -24L), class = "data.frame")

使用的最少代码是:

par(mfrow= c(1,2))
plot(dframe$time_hour ,dframe$power,type="l",xlab = "Hour of day", ylab = "power" )
plot(dframe$time_hour ,dframe$temperature,type="l",xlab = "Hour of day", ylab = "Temperature" )
1个回答

这是一个典型的时间序列问题。第一步是确保您的时间序列是平稳的,请参阅此处了解为什么这是必要的。

所以我们首先做

dframe$power_diff <- c(NA, diff(dframe$power))
plot(dframe$power_diff, type = "l")

给,

功率差异

接下来我们要考虑一个ARIMAX 模型作为本练习的一部分,我们想知道时间序列中是否存在依赖关系,即所谓的自回归项。我们可以使用以下方法进行研究,

acf(na.omit(dframe$power_diff))

这使,

acf_power_diff

在该图中,我们看到在滞后 1 处有一个正自回归项,显着性水平为 95%,我们基于观察到第二条线(即滞后 1)高于蓝色虚线而得出结论。

接下来我们要拟合一个 ARIMAX 模型。

# Convert data to ts object
power_data <- ts(data = dframe$power_diff[-1], frequency = 8766, start = c(2016, 1, 1))
temp_data <- ts(data = dframe$temp_diff[-1], frequency = 8766, start = c(2016, 1, 1))

# Build the model.
m <- Arima(power_data, order = c(1, 0, 0), xreg = temp_data)

# Let's see how our fit is.
plot(power_data)
lines(fitted(m), col = "blue")

这给出了这个结果,

预报

您可以使用 ARIMA(p, i, q) 项。我们应该保留,因为我们发现 AR 项在滞后 1 时很重要。如果我们添加一个 MA(1),我们会发现一个模型对于我们的初始模型具有 a与 a 因此,您可以使用以下方法创建最佳模型,p=1MAPE=260.46MAPE=272.62

m2 <- Arima(power_data, order = c(1, 1, 0), xreg = temp_data)
lines(fitted(m2), col = 'red')

会导致, 阿里马斯

当然,我们可以使用auto.arima(). 此功能将搜索最佳arima模型,

m3 <- auto.arima(power_data, xreg = temp_data)
lines(fitted(m3), col = 'green')

这会给你, auto_arima

您会看到每个模型在尖峰中的拟合度都很差。为了改善这一点,您可以引入一个虚拟变量,

xdata <- ts(data = as.matrix(cbind(temp_data, dframe$power_diff[-1] > 20)), frequency = 8766, start =c(2016,1,1))
m_dummy <- auto.arima(power_data, xreg = xdata)
lines(fitted(m_dummy), col = 'orange')

这给了我们以下结果, 假的

我们看到这个模型给了我们更好的结果。因此,如果您可以将 dummy 与某个时间点相关联,您就可以创建一个非常适合的模型。

根据 Occam's Razor,您应该尽量保持模型简单。因此,我建议为您的所有时间段构建一个模型,而不是您在问题中建议的三个单独的模型。

您可以使用 将其转回原始时间序列cumsum希望这可以帮助。