使用交叉验证评估 R 中的 Prophet 模型

Evaluating Prophet model in R, using cross-validation

我正在尝试在 R 中交叉验证 Prophet 模型。 问题 - 这个包不能很好地处理月度数据。

我成功构建了模型

甚至使用了自定义的每月季节性。

根据此工具的作者的推荐。

但无法交叉验证月度数据。尝试遵循 GitHub issue 中的建议,但遗漏了一些内容。

目前我的代码是这样的

model1_cv <- cross_validation(model1, initial = 156, period = 365/12, as.difftime(horizon = 365/12, units = "days"))

更新:

根据这个问题的答案,我可视化了 CV 结果。这里有一些问题。我使用了完整数据和部分数据。

指标看起来也不太好

我刚刚用软件包中的训练数据进行了一些测试,据我了解,该软件包不太适合月度预测,这部分:[...] as.difftime(365/12, units = "days") [...] 似乎只是为了证明一个月有 30 多天的大小。这意味着您可以使用它而不是仅仅使用 365/12 por "period" and/or "horizo​​n"。我注意到的一件事是,每个描述的两个参数都是整数类型,但是当你查看函数时,它们是根据 as.datediff() 计算的,所以它们实际上是双精度的。

library(dplyr)
library(prophet)
library(data.table)

#training data
df <- data.table::fread("ds     y
              1992-01-01    146376
              1992-02-01    147079
              1992-03-01    159336
              1992-04-01    163669
              1992-05-01    170068
              1992-06-01    168663
              1992-07-01    169890
              1992-08-01    170364
              1992-09-01    164617
              1992-10-01    173655
              1992-11-01    171547
              1992-12-01    208838
              1993-01-01    153221
              1993-02-01    150087
              1993-03-01    170439
              1993-04-01    176456
              1993-05-01    182231
              1993-06-01    181535
              1993-07-01    183682
              1993-08-01    183318
              1993-09-01    177406
              1993-10-01    182737
              1993-11-01    187443
              1993-12-01    224540
              1994-01-01    161349
              1994-02-01    162841
              1994-03-01    192319
              1994-04-01    189569
              1994-05-01    194927
              1994-06-01    197946
              1994-07-01    193355
              1994-08-01    202388
              1994-09-01    193954
              1994-10-01    197956
              1994-11-01    202520
              1994-12-01    241111
              1995-01-01    175344
              1995-02-01    172138
              1995-03-01    201279
              1995-04-01    196039
              1995-05-01    210478
              1995-06-01    211844
              1995-07-01    203411
              1995-08-01    214248
              1995-09-01    202122
              1995-10-01    204044
              1995-11-01    212190
              1995-12-01    247491
              1996-01-01    185019
              1996-02-01    192380
              1996-03-01    212110
              1996-04-01    211718
              1996-05-01    226936
              1996-06-01    217511
              1996-07-01    218111")

df <- df %>% 
  dplyr::mutate(ds = as.Date(ds))

model <- prophet::prophet(df)

(tscv.myfit <- prophet::cross_validation(model, horizon = 365/12, units = "days", period = 365/12, initial = 365/12 * 12 * 3))

         y         ds     yhat yhat_lower yhat_upper              cutoff
 1: 175344 1995-01-01 170988.8   170145.9   171828.0 1994-12-31 02:00:00
 2: 172138 1995-02-01 178117.4   176975.2   179070.2 1995-01-30 12:00:00
 3: 201279 1995-03-01 211462.8   210277.4   212670.8 1995-01-30 12:00:00
 4: 196039 1995-04-01 200113.9   198079.5   201977.8 1995-03-01 22:00:00
 5: 210478 1995-05-01 202100.5   200390.8   203797.9 1995-04-01 08:00:00
 6: 211844 1995-06-01 208330.5   206229.9   210497.4 1995-05-01 18:00:00
 7: 203411 1995-07-01 202563.8   200786.5   204313.0 1995-06-01 04:00:00
 8: 214248 1995-08-01 214639.6   212748.3   216461.3 1995-07-01 14:00:00
 9: 202122 1995-09-01 204954.0   203048.9   206768.4 1995-08-31 12:00:00
10: 204044 1995-10-01 205097.5   203209.7   206882.3 1995-09-30 22:00:00
11: 212190 1995-11-01 213586.7   211728.1   215617.6 1995-10-31 08:00:00
12: 247491 1995-12-01 251518.8   249708.2   253589.2 1995-11-30 18:00:00
13: 185019 1996-01-01 182403.7   180520.1   184494.7 1995-12-31 04:00:00
14: 192380 1996-02-01 184722.9   182772.7   186686.9 1996-01-30 14:00:00
15: 212110 1996-03-01 205020.1   202823.2   206996.9 1996-01-30 14:00:00
16: 211718 1996-04-01 214514.0   211891.9   217175.3 1996-03-31 14:00:00
17: 226936 1996-05-01 218845.2   216133.8   221420.4 1996-03-31 14:00:00
18: 217511 1996-06-01 218672.2   216007.8   221459.9 1996-05-31 14:00:00
19: 218111 1996-07-01 221156.1   218540.7   224184.1 1996-05-31 14:00:00

截止时间并不像人们预期的那样规律 - 我猜这是由于以某种方式使用了每月的平均天数 - 尽管我无法弄清楚其中的逻辑。您可以将 365/12 替换为 as.difftime(365/12, units = "days") 并会得到相同的结果。

但是如果你使用 (365+365+365+366) / 48 而不是因为 29.02.您每个月的平均天数略有不同,这会导致不同的输出:

(tscv.myfit_2 <- prophet::cross_validation(model, horizon = (365+365+365+366)/48, units = "days", period = (365+365+365+366)/48, initial = (365+365+365+366)/48 * 12 * 3))

         y         ds     yhat yhat_lower yhat_upper              cutoff
 1: 172138 1995-02-01 178117.4   177075.3   179203.9 1995-01-29 13:30:00
 2: 201279 1995-03-01 211462.8   210340.5   212607.3 1995-01-29 13:30:00
 3: 196039 1995-04-01 200113.9   198022.6   202068.1 1995-03-31 13:30:00
 4: 210478 1995-05-01 204100.2   202009.8   206098.7 1995-03-31 13:30:00
 5: 211844 1995-06-01 208330.5   206114.5   210515.8 1995-05-31 13:30:00
 6: 203411 1995-07-01 202606.0   200319.1   204663.4 1995-05-31 13:30:00
 7: 214248 1995-08-01 214639.6   212684.4   216495.7 1995-07-31 22:30:00
 8: 202122 1995-09-01 204954.0   203127.7   206951.0 1995-08-31 09:00:00
 9: 204044 1995-10-01 205097.5   203285.3   207036.5 1995-09-30 19:30:00
10: 212190 1995-11-01 213586.7   211516.8   215516.2 1995-10-31 06:00:00
11: 247491 1995-12-01 251518.8   249658.3   253590.1 1995-11-30 16:30:00
12: 185019 1996-01-01 182403.7   180359.7   184399.2 1995-12-31 03:00:00
13: 192380 1996-02-01 184722.9   182652.4   186899.8 1996-01-30 13:30:00
14: 212110 1996-03-01 205020.1   203040.3   207171.9 1996-01-30 13:30:00
15: 211718 1996-04-01 214514.0   211942.6   217252.6 1996-03-31 13:30:00
16: 226936 1996-05-01 218845.2   216203.1   221506.5 1996-03-31 13:30:00
17: 217511 1996-06-01 218672.2   215823.9   221292.4 1996-05-31 13:30:00
18: 218111 1996-07-01 221156.1   218236.7   223862.0 1996-05-31 13:30:00

形成这种行为我会说周围的工作并不理想,特别是取决于您希望交叉验证在滚动月份方面的精确程度。如果您需要准确的截止点,您可以编写自己的函数并从起点开始预测一个月,收集这些结果并进行最终比较。我更相信这种方法而不是周围的工作。