r - Prophet模型中假期的不确定性很大

标签 r time-series facebook-prophet

我正在使用 Prophet 构建一个时间序列模型,并因假期周围的不确定性而出现一些奇怪的行为,我不明白。

数据来自 Google 趋势,与“花”一词的搜索相关。

library(dplyr)
library(gtrendsR)
library(prophet)

flowers <- gtrends("flowers")$interest_over_time

flowers <- flowers %>% select(ds = date, y = hits)

正如您所料,该时间序列在两个重要日子附近出现峰值:情人节和母亲节。

为了在我的模型中考虑到这些天,我创建了一个数据框,其中包含感兴趣期间的相关日期。

holidays <- rbind(
  data.frame(
    holiday = "mothers_day",
    ds = as.Date(c(
      # Second Sunday of May.
      '2014-05-11',
      '2015-05-10',
      '2016-05-08',
      '2017-05-14',
      '2018-05-13',
      '2019-05-12',
      '2020-05-10'
    )),
    lower_window = -7,       # Extend holiday to 7 days before nominal date
    upper_window = +7,       # Extend holiday to 7 days after nominal date
    prior_scale = 1
  ),
  data.frame(
    holiday = "valentines_day",
    ds = as.Date(c(
      '2014-02-14',
      '2015-02-14',
      '2016-02-14',
      '2017-02-14',
      '2018-02-14',
      '2019-02-14',
      '2020-02-14'
    )),
    lower_window = -7,       # Extend holiday to 7 days before nominal date
    upper_window = +7,       # Extend holiday to 7 days after nominal date
    prior_scale = 1
  )
)

由于时间序列数据以周为间隔,因此我使用 lower_windowupper_window 来扩展名义日期两侧假期的影响。

现在利用这些假期休息一下。

flowers_prophet <- prophet(
  holidays = holidays,
  mcmc.samples = 300
)

flowers_prophet <- fit.prophet(
  flowers_prophet,
  flowers
)

有了模型,我们就可以做出预测。

flowers_future <- make_future_dataframe(flowers_prophet,
                                        periods = 52,
                                        freq = 'week')

flowers_forecast <- predict(flowers_prophet, flowers_future)

prophet_plot_components(flowers_prophet, flowers_forecast)

这就是事情变得奇怪的地方。

Components of time series predictions

趋势和年度变化看起来完全合理。与历史节日相关的变化看起来也不错。 2020 年母亲节看起来不错。但2020年情人节的预测值较小(相对于历史值),不确定性极大。

实际时间序列看起来不错:历史值拟合得很好,并且对 2020 年母亲节的预测看起来非常合理。但 2020 年情人节的值(value)和不确定性看起来不太对劲。

Time series prediction

如果有人能帮助我理解为什么这两个假期的预测如此不同,我将不胜感激。

最佳答案

由于情人节始终是 14 号,但 Google 趋势数据每 7 天一次,因此历史数据存在偏差。 2016 年,峰值出现在“2016-02-07”这一周,即节假日前 1 整周,而下一年的峰值则称为“2017-02-12”,仅在节假日前 2 天。

library(lubridate)
flowers %>%  
  filter(month(date) == 2) %>%
  group_by(yr = year(date)) %>%
  arrange(-hits) %>%
  slice(1)

# A tibble: 5 x 7
# Groups:   yr [5]
  date                 hits keyword geo   gprop category    yr
  <dttm>              <int> <chr>   <chr> <chr>    <int> <dbl>
1 2015-02-08 00:00:00    87 flowers world web          0  2015
2 2016-02-07 00:00:00    79 flowers world web          0  2016
3 2017-02-12 00:00:00    88 flowers world web          0  2017
4 2018-02-11 00:00:00    91 flowers world web          0  2018
5 2019-02-10 00:00:00    89 flowers world web          0  2019

我怀疑问题在于先知在某些情况下将 14 日解释为接近峰值,有时甚至是峰值后整整一周。它出现峰值,但其时间与您指定的假期日期不一致。我不太确定如何在不手动消除时间不一致的情况下解决这个问题。

如果我们调整假期以使其与数据中对应的日期保持一致,我们会得到更好的拟合:

...  # using this list for valentines day dates, corresponding to peaks in data
holiday = "valentines_day",
    ds = as.Date(c(
      '2015-02-08',
      '2016-02-07',
      '2017-02-12',
      '2018-02-11',
      '2019-02-10',
      '2020-02-09'  # Corresponds to the Sunday beforehand, like prior spikes here
    ))
...

结果:

trend chart

关于r - Prophet模型中假期的不确定性很大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58546363/

相关文章:

r - 使用 R markdown 和 knitr 生成 PDF 文件,将 R 对象用于 YAML header

r - 为什么 ACF 不绘制滞后

time-series - 如何找到两个时间序列之间的偏移量以最小化它们的欧氏距离?

pandas - Facebook NeuralProphet - 生成模型文件

python - 当我尝试导入 Facebook 先知 : pip install fbprophet . .. 我总是收到这个错误

r - 如果列中包含子字符串,如何检查列中的每一行

r - 如何在 R 中使用 gDistance 计算距离矩阵?

r - 将列向量乘以 RcppArmadillo 中的数值标量

python - 从数据、周期范围和聚合函数创建 Pandas TimeSeries

python - fbprophet 年度季节性值太高