使用 R 中的多元线性回归和滞后变量进行长期预测
Making a long-term forecast with multiple linear regression and lagged variables in R
您好,我有兴趣对未来 7 个多月的每小时电力负荷进行预测。我的数据集包括大约 5 年半的每小时负荷和温度数据。我要实现的模型是一个多元线性回归,包括温度作为自变量和月份、工作日和小时作为分类变量,以及负载滞后的 24 个变量; lag1为前一小时的电负荷值,lag2为当前值前2小时的电能负荷值,依此类推
my_df <- read.csv(file = "https://raw.githubusercontent.com/Argiro1983/Load/main/my_df.csv", sep=";")
library(Hmisc)
mod_lm <- lm(LOAD ~ TEMPERATURE + MONTH + WEEKDAY + HOUR + Lag(LOAD,1) + Lag(LOAD, 2) + Lag(LOAD, 3) + Lag(LOAD, 4) + Lag(LOAD,5)+
Lag(LOAD, 6) + Lag(LOAD, 7) + Lag(LOAD, 8) + Lag(LOAD,9) + Lag(LOAD, 10) + Lag(LOAD,11)+ Lag(LOAD, 12)+
Lag(LOAD, 13)+ Lag(LOAD, 14) + Lag(LOAD, 15) + Lag(LOAD, 16) + Lag(LOAD, 17) + Lag(LOAD, 18)+
Lag(LOAD, 19) + Lag(LOAD,20) + Lag(LOAD, 21) + Lag(LOAD, 22) +Lag(LOAD, 23)+
Lag(LOAD,24), data=my_df)
summary(mod_lm)
模型看起来像这样:
Call:
lm(formula = dyn(LOAD ~ TEMPERATURE + MONTH + WEEKDAY + HOUR +
lag(LOAD, 1) + lag(LOAD, 2) + lag(LOAD, 3) + lag(LOAD, 4) +
lag(LOAD, 5) + lag(LOAD, 6) + lag(LOAD, 7) + lag(LOAD, 8) +
lag(LOAD, 9) + lag(LOAD, 10) + lag(LOAD, 11) + lag(LOAD,
12) + lag(LOAD, 13) + lag(LOAD, 14) + lag(LOAD, 15) + lag(LOAD,
16) + lag(LOAD, 17) + lag(LOAD, 18) + lag(LOAD, 19) + lag(LOAD,
20) + lag(LOAD, 21) + lag(LOAD, 22) + lag(LOAD, 23) + lag(LOAD,
24)), data = my_df)
Residuals:
Min 1Q Median 3Q Max
-1155.48 -76.38 -3.80 72.12 1540.34
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 96.297801 5.399303 17.835 < 2e-16 ***
TEMPERATURE 0.147311 0.087598 1.682 0.092638 .
MONTH -0.013815 0.186592 -0.074 0.940980
WEEKDAY -20.396726 0.361845 -56.369 < 2e-16 ***
HOUR 1.290159 0.171243 7.534 5.01e-14 ***
lag(LOAD, 1) 1.375390 0.004447 309.307 < 2e-16 ***
lag(LOAD, 2) -0.666860 0.007378 -90.379 < 2e-16 ***
lag(LOAD, 3) 0.205219 0.007890 26.010 < 2e-16 ***
lag(LOAD, 4) -0.176901 0.007905 -22.377 < 2e-16 ***
lag(LOAD, 5) 0.128568 0.007932 16.208 < 2e-16 ***
lag(LOAD, 6) -0.028096 0.007960 -3.530 0.000417 ***
lag(LOAD, 7) -0.058609 0.007950 -7.372 1.71e-13 ***
lag(LOAD, 8) 0.164145 0.007905 20.765 < 2e-16 ***
lag(LOAD, 9) -0.225412 0.007868 -28.650 < 2e-16 ***
lag(LOAD, 10) 0.133046 0.007940 16.757 < 2e-16 ***
lag(LOAD, 11) 0.014815 0.007948 1.864 0.062318 .
lag(LOAD, 12) -0.035893 0.007951 -4.515 6.36e-06 ***
lag(LOAD, 13) 0.025532 0.007956 3.209 0.001332 **
lag(LOAD, 14) -0.028748 0.007962 -3.611 0.000306 ***
lag(LOAD, 15) -0.095531 0.007928 -12.050 < 2e-16 ***
lag(LOAD, 16) 0.227563 0.007876 28.894 < 2e-16 ***
lag(LOAD, 17) -0.189406 0.007912 -23.939 < 2e-16 ***
lag(LOAD, 18) 0.070704 0.007947 8.897 < 2e-16 ***
lag(LOAD, 19) 0.020112 0.007954 2.528 0.011462 *
lag(LOAD, 20) -0.103368 0.007936 -13.025 < 2e-16 ***
lag(LOAD, 21) 0.181176 0.007901 22.931 < 2e-16 ***
lag(LOAD, 22) -0.204949 0.007907 -25.919 < 2e-16 ***
lag(LOAD, 23) 0.533351 0.007334 72.723 < 2e-16 ***
lag(LOAD, 24) -0.271700 0.004480 -60.654 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 131.8 on 46795 degrees of freedom
(24 observations deleted due to missingness)
Multiple R-squared: 0.9871, Adjusted R-squared: 0.9871
F-statistic: 1.28e+05 on 28 and 46795 DF, p-value: < 2.2e-16
如何构建我的 predict
函数,以便它生成具有我的预测温度 table 长度的预测(5736 个值)并考虑“预测的”滞后负载变量?我一直在使用 dyn 包时遇到困难,出于某种原因,滞后变量产生零估计。
forecast_df <- read.csv(file = "https://raw.githubusercontent.com/Argiro1983/Load/main/forecast_df.csv", sep=";")
这显然行不通:
pred <-predict(mod_lm, newdata = forecast_df)
提前致谢,如有任何想法,我们将不胜感激。
我无法加载您的数据,但我认为您需要 运行 循环内的回归 - 在每个循环结束时,新预测被重新编码为 lag1
,旧的 lag1
变为 lag2
等...在循环 运行s 从第一次(大概是现在?)到所有 5736 个值。
您可以将结果存储在长 table 中,时间作为一列,预测作为另一列。然后在每个循环的末尾(或开始)将最近的 24 个值散布到新列中以用作预测变量。添加您的其他预测变量(温度等),然后再次 运行 predict
,将新预测添加到您的长 table... 重复直到完成。
使用问题中的 my_df 将其转换为 zoo,然后 运行 dyn$lm。最初的问题是有一个日期时间字段是字符,因此 zoo(my_df) 将其转换为字符对象。如果我们使用 read.zoo 并将日期时间字段转换为 POSIXct 并告诉它该列是索引 - read.zoo 假定第一列是索引,除非另有说明 - 然后它起作用.另请注意,数据中有日期时间与夏令时冲突,因此时区必须指定为UTC。
接下来按照 ?dyn
末尾的代码进行预测。由于这对于大量数据来说可能非常慢,我们刚刚在下面显示了 3 个预测。
根据我的评论,请确保未加载 dplyr,因为它会破坏延迟。
library(dyn)
z <- read.zoo(my_df, format = "%d/%m/%Y %H:%M", tz = "UTC")
fo <- LOAD ~ TEMPERATURE + MONTH + WEEKDAY + HOUR + lag(LOAD, -(1:24))
fm <- dyn$lm(fo, z)
fc.orig <- read.zoo(forecast_df, format = "%d/%m/%Y %H:%M", tz = "UTC")
# fc <- fc.orig
fc <- head(fc.orig, 3)
LOAD0 <- zoo(cbind(LOAD = 0), time(fc))
both <- rbind(z, cbind(LOAD0, fc))
for(i in seq(nrow(z) + 1, nrow(both))) {
fit <- dyn$lm(fo, both, subset = seq_len(i-1))
both[i, "LOAD"] <- tail(predict(fit, both[1:i, ]), 1)
}
# extract the forecast rows
fc_new <- both[seq(nrow(z) + 1, nrow(both)), ]
备注
my_df <- read.csv(file =
"https://raw.githubusercontent.com/Argiro1983/Load/main/my_df.csv", sep=";")
forecast_df <- read.csv(file = "https://raw.githubusercontent.com/Argiro1983/Load/main/forecast_df.csv", sep=";")
您好,我有兴趣对未来 7 个多月的每小时电力负荷进行预测。我的数据集包括大约 5 年半的每小时负荷和温度数据。我要实现的模型是一个多元线性回归,包括温度作为自变量和月份、工作日和小时作为分类变量,以及负载滞后的 24 个变量; lag1为前一小时的电负荷值,lag2为当前值前2小时的电能负荷值,依此类推
my_df <- read.csv(file = "https://raw.githubusercontent.com/Argiro1983/Load/main/my_df.csv", sep=";")
library(Hmisc)
mod_lm <- lm(LOAD ~ TEMPERATURE + MONTH + WEEKDAY + HOUR + Lag(LOAD,1) + Lag(LOAD, 2) + Lag(LOAD, 3) + Lag(LOAD, 4) + Lag(LOAD,5)+
Lag(LOAD, 6) + Lag(LOAD, 7) + Lag(LOAD, 8) + Lag(LOAD,9) + Lag(LOAD, 10) + Lag(LOAD,11)+ Lag(LOAD, 12)+
Lag(LOAD, 13)+ Lag(LOAD, 14) + Lag(LOAD, 15) + Lag(LOAD, 16) + Lag(LOAD, 17) + Lag(LOAD, 18)+
Lag(LOAD, 19) + Lag(LOAD,20) + Lag(LOAD, 21) + Lag(LOAD, 22) +Lag(LOAD, 23)+
Lag(LOAD,24), data=my_df)
summary(mod_lm)
模型看起来像这样:
Call:
lm(formula = dyn(LOAD ~ TEMPERATURE + MONTH + WEEKDAY + HOUR +
lag(LOAD, 1) + lag(LOAD, 2) + lag(LOAD, 3) + lag(LOAD, 4) +
lag(LOAD, 5) + lag(LOAD, 6) + lag(LOAD, 7) + lag(LOAD, 8) +
lag(LOAD, 9) + lag(LOAD, 10) + lag(LOAD, 11) + lag(LOAD,
12) + lag(LOAD, 13) + lag(LOAD, 14) + lag(LOAD, 15) + lag(LOAD,
16) + lag(LOAD, 17) + lag(LOAD, 18) + lag(LOAD, 19) + lag(LOAD,
20) + lag(LOAD, 21) + lag(LOAD, 22) + lag(LOAD, 23) + lag(LOAD,
24)), data = my_df)
Residuals:
Min 1Q Median 3Q Max
-1155.48 -76.38 -3.80 72.12 1540.34
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 96.297801 5.399303 17.835 < 2e-16 ***
TEMPERATURE 0.147311 0.087598 1.682 0.092638 .
MONTH -0.013815 0.186592 -0.074 0.940980
WEEKDAY -20.396726 0.361845 -56.369 < 2e-16 ***
HOUR 1.290159 0.171243 7.534 5.01e-14 ***
lag(LOAD, 1) 1.375390 0.004447 309.307 < 2e-16 ***
lag(LOAD, 2) -0.666860 0.007378 -90.379 < 2e-16 ***
lag(LOAD, 3) 0.205219 0.007890 26.010 < 2e-16 ***
lag(LOAD, 4) -0.176901 0.007905 -22.377 < 2e-16 ***
lag(LOAD, 5) 0.128568 0.007932 16.208 < 2e-16 ***
lag(LOAD, 6) -0.028096 0.007960 -3.530 0.000417 ***
lag(LOAD, 7) -0.058609 0.007950 -7.372 1.71e-13 ***
lag(LOAD, 8) 0.164145 0.007905 20.765 < 2e-16 ***
lag(LOAD, 9) -0.225412 0.007868 -28.650 < 2e-16 ***
lag(LOAD, 10) 0.133046 0.007940 16.757 < 2e-16 ***
lag(LOAD, 11) 0.014815 0.007948 1.864 0.062318 .
lag(LOAD, 12) -0.035893 0.007951 -4.515 6.36e-06 ***
lag(LOAD, 13) 0.025532 0.007956 3.209 0.001332 **
lag(LOAD, 14) -0.028748 0.007962 -3.611 0.000306 ***
lag(LOAD, 15) -0.095531 0.007928 -12.050 < 2e-16 ***
lag(LOAD, 16) 0.227563 0.007876 28.894 < 2e-16 ***
lag(LOAD, 17) -0.189406 0.007912 -23.939 < 2e-16 ***
lag(LOAD, 18) 0.070704 0.007947 8.897 < 2e-16 ***
lag(LOAD, 19) 0.020112 0.007954 2.528 0.011462 *
lag(LOAD, 20) -0.103368 0.007936 -13.025 < 2e-16 ***
lag(LOAD, 21) 0.181176 0.007901 22.931 < 2e-16 ***
lag(LOAD, 22) -0.204949 0.007907 -25.919 < 2e-16 ***
lag(LOAD, 23) 0.533351 0.007334 72.723 < 2e-16 ***
lag(LOAD, 24) -0.271700 0.004480 -60.654 < 2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 131.8 on 46795 degrees of freedom
(24 observations deleted due to missingness)
Multiple R-squared: 0.9871, Adjusted R-squared: 0.9871
F-statistic: 1.28e+05 on 28 and 46795 DF, p-value: < 2.2e-16
如何构建我的 predict
函数,以便它生成具有我的预测温度 table 长度的预测(5736 个值)并考虑“预测的”滞后负载变量?我一直在使用 dyn 包时遇到困难,出于某种原因,滞后变量产生零估计。
forecast_df <- read.csv(file = "https://raw.githubusercontent.com/Argiro1983/Load/main/forecast_df.csv", sep=";")
这显然行不通:
pred <-predict(mod_lm, newdata = forecast_df)
提前致谢,如有任何想法,我们将不胜感激。
我无法加载您的数据,但我认为您需要 运行 循环内的回归 - 在每个循环结束时,新预测被重新编码为 lag1
,旧的 lag1
变为 lag2
等...在循环 运行s 从第一次(大概是现在?)到所有 5736 个值。
您可以将结果存储在长 table 中,时间作为一列,预测作为另一列。然后在每个循环的末尾(或开始)将最近的 24 个值散布到新列中以用作预测变量。添加您的其他预测变量(温度等),然后再次 运行 predict
,将新预测添加到您的长 table... 重复直到完成。
使用问题中的 my_df 将其转换为 zoo,然后 运行 dyn$lm。最初的问题是有一个日期时间字段是字符,因此 zoo(my_df) 将其转换为字符对象。如果我们使用 read.zoo 并将日期时间字段转换为 POSIXct 并告诉它该列是索引 - read.zoo 假定第一列是索引,除非另有说明 - 然后它起作用.另请注意,数据中有日期时间与夏令时冲突,因此时区必须指定为UTC。
接下来按照 ?dyn
末尾的代码进行预测。由于这对于大量数据来说可能非常慢,我们刚刚在下面显示了 3 个预测。
根据我的评论,请确保未加载 dplyr,因为它会破坏延迟。
library(dyn)
z <- read.zoo(my_df, format = "%d/%m/%Y %H:%M", tz = "UTC")
fo <- LOAD ~ TEMPERATURE + MONTH + WEEKDAY + HOUR + lag(LOAD, -(1:24))
fm <- dyn$lm(fo, z)
fc.orig <- read.zoo(forecast_df, format = "%d/%m/%Y %H:%M", tz = "UTC")
# fc <- fc.orig
fc <- head(fc.orig, 3)
LOAD0 <- zoo(cbind(LOAD = 0), time(fc))
both <- rbind(z, cbind(LOAD0, fc))
for(i in seq(nrow(z) + 1, nrow(both))) {
fit <- dyn$lm(fo, both, subset = seq_len(i-1))
both[i, "LOAD"] <- tail(predict(fit, both[1:i, ]), 1)
}
# extract the forecast rows
fc_new <- both[seq(nrow(z) + 1, nrow(both)), ]
备注
my_df <- read.csv(file =
"https://raw.githubusercontent.com/Argiro1983/Load/main/my_df.csv", sep=";")
forecast_df <- read.csv(file = "https://raw.githubusercontent.com/Argiro1983/Load/main/forecast_df.csv", sep=";")