Prophet 模型中假期的不确定性很大
Large uncertainties for holidays in Prophet model
我正在使用 Prophet 构建一个时间序列模型,并在节假日期间出现一些我不理解的不确定性的奇怪行为。
数据来自 Google Trends 并与搜索字词 "flowers" 相关。
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_window
和 upper_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)
这就是事情变得奇怪的地方。
趋势和年度变化看起来非常合理。与历史假期相关的变化看起来也不错。 2020 年母亲节看起来不错。但是,2020年情人节的预测值很小(相对于历史值),不确定性极大。
实际时间序列看起来不错:历史值拟合得很好,对 2020 年母亲节的预测看起来非常合理。但是 2020 年情人节的价值和不确定性看起来并不正确。
如果有人能帮助我理解为什么这两个假期的预测如此不同,我将不胜感激。
由于情人节始终是 14 日,但 google 趋势数据是每 7 天一次,因此历史数据存在偏差。 2016年高峰期出现在“2016-02-07”周,即节前整整一周,而次年高峰周称为“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
))
...
导致:
我正在使用 Prophet 构建一个时间序列模型,并在节假日期间出现一些我不理解的不确定性的奇怪行为。
数据来自 Google Trends 并与搜索字词 "flowers" 相关。
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_window
和 upper_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)
这就是事情变得奇怪的地方。
趋势和年度变化看起来非常合理。与历史假期相关的变化看起来也不错。 2020 年母亲节看起来不错。但是,2020年情人节的预测值很小(相对于历史值),不确定性极大。
实际时间序列看起来不错:历史值拟合得很好,对 2020 年母亲节的预测看起来非常合理。但是 2020 年情人节的价值和不确定性看起来并不正确。
如果有人能帮助我理解为什么这两个假期的预测如此不同,我将不胜感激。
由于情人节始终是 14 日,但 google 趋势数据是每 7 天一次,因此历史数据存在偏差。 2016年高峰期出现在“2016-02-07”周,即节前整整一周,而次年高峰周称为“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
))
...
导致: