mitchelloharawild / fable.prophet

fable extension for the prophet forecasting procedure
https://pkg.mitchelloharawild.com/fable.prophet
55 stars 8 forks source link

Errors with annual seasonal periods #8

Closed mpjashby closed 5 years ago

mpjashby commented 5 years ago

I'm trying to specify an annual seasonal term for a prophet model for daily data using the season(period = "year") special, but get an error. For example, using daily counts of crime data over three years (with a model with weekly seasonality, for comparison):

library("crimedata")
library("fable")
library("fable.prophet")
library("tsibble")
library("tidyverse")

daily_crimes <- get_crime_data(years = 2010:2013, cities = "New York") %>% 
  mutate(date = as_date(date_single)) %>% 
  count(date) %>% 
  filter(!is.na(date)) %>% 
  as_tsibble(index = date)

prophet_models <- model(
  daily_crimes,
  prophet_year = prophet(n ~ growth() + season(period = "year")),
  prophet_365 = prophet(n ~ growth() + season(period = 365)),
  prophet_week = prophet(n ~ growth() + season(period = "week"))
)

Both the prophet_year and prophet_365 models give (different) errors:

1: 1 error encountered for prophet_year
[1] invalid class “Period” object: periods must have integer values

2: 1 error encountered for prophet_365
[1] invalid type of argument[1]: 'language'

while the prophet_week model runs as expected.

I interpreted the error with season(period = "year") as requiring seasonal periods to be an integer number of days, but the documentation at ?prophet seems to imply that non-integer periods are possible, in the explanation of the use of the name parameter:

The name of the seasonal term (allowing you to name an annual pattern as 'annual' instead of 'year' or 365.25 for example).

Looking at the documentation for the underlying prophet method, it shows several examples of non-integer seasonality, so I wonder if the error is in fable.prophet.

The error with season(period = 365) was unexpected because the documentation at ?prophet states that the value of period can be numeric:

The periodic nature of the seasonality. If a number is given, this will be treated as days in the seasonal period. If a character is given, it will be parsed using lubridate::as.period, allowing seasonal periods such as "2 years".

How should I specify a prophet model with an annual seasonal term?

mitchelloharawild commented 5 years ago

Oops, the code for my error had an error! The issue is that prophet has defaults for the order of harmonics for annual (365.25), weekly (7) and daily (1) frequencies. Instead of 365, you should use 365.25 (for leap years), or specify your own fourier order.

The error message should be better for this now.

mpjashby commented 5 years ago

The new error message for season(period = 365) is definitely much better – thanks for that and for the quick reply. But I'm now getting some new issues, as well as the remaining problem with season(period = "year").

If I change the model() function in the code above to:

prophet_models <- model(
    daily_crimes,
    prophet_year = prophet(n ~ growth() + season(period = "year")),
    prophet_365 = prophet(n ~ growth() + season(period = 365)),
    prophet_365_order = prophet(n ~ growth() + season(period = 365, order = 4)),
    prophet_week = prophet(n ~ growth() + season(period = "week"))
)

I get:

1: 1 error encountered for prophet_year
[1] invalid class “Period” object: periods must have integer values

2: 1 error encountered for prophet_365
[1] Unable to add season(period = 365) to the model. The fourier order has no 
    default, and must be specified with `order = ?`.

3: 1 error encountered for prophet_365_order
[1] Can't find column `365` in `.data`.

So I suppose I have two questions:

  1. how can I get season(period = "year") to work for daily data, and
  2. why is 365 in season(period = 365, order = ?) treated as a column name rather than a number?

I'm primarily interested in the first question, because if season(period = "year") works then I suppose there is probably little need for season(period = 365, order = ?)!

mitchelloharawild commented 5 years ago

Okay, this would be an issue with moving from Python's prophet to R's prophet. I'll open a separate issue for this.