(Air_passengers-Prophet_with_Bayesian_workflow)=

Air passengers - Prophet-like model

:::{post} April, 2022 :tags: time series, prophet :category: intermediate :author: Marco Gorelli, Danh Phan :::

We're going to look at the "air passengers" dataset, which tracks the monthly totals of a US airline passengers from 1949 to 1960. We could fit this using the Prophet model {cite:p}taylor2018forecasting (indeed, this dataset is one of the examples they provide in their documentation), but instead we'll make our own Prophet-like model in PyMC3. This will make it a lot easier to inspect the model's components and to do prior predictive checks (an integral component of the Bayesian workflow {cite:p}gelman2020bayesian).

Before we begin: visualise the data

There's an increasing trend, with multiplicative seasonality. We'll fit a linear trend, and "borrow" the multiplicative seasonality part of it from Prophet.

Part 0: scale the data

First, we'll scale time to be between 0 and 1:

Next, for the target variable, we divide by the maximum. We do this, rather than standardising, so that the sign of the observations in unchanged - this will be necessary for the seasonality component to work properly later on.

Part 1: linear trend

The model we'll fit, for now, will just be

Passengersα+β time\text{Passengers} \sim \alpha + \beta\ \text{time}

First, let's try using the default priors set by prophet, and we'll do a prior predictive check:

We can do better than this. These priors are evidently too wide, as we end up with implausibly many passengers. Let's try setting tighter priors.

Cool. Before going on to anything more complicated, let's try conditioning on the data and doing a posterior predictive check:

Part 2: enter seasonality

To model seasonality, we'll "borrow" the approach taken by Prophet - see the Prophet paper {cite:p}taylor2018forecasting for details, but the idea is to make a matrix of Fourier features which get multiplied by a vector of coefficients. As we'll be using multiplicative seasonality, the final model will be

Passengers(α+β time)(1+seasonality)\text{Passengers} \sim (\alpha + \beta\ \text{time}) (1 + \text{seasonality})

Again, let's use the default Prophet priors, just to see what happens.

Again, this seems implausible. The default priors are too wide for our use-case, and it doesn't make sense to use them when we can do prior predictive checks to set more sensible ones. Let's try with some narrower ones:

Seems a lot more believable. Time for a posterior predictive check:

Neat!

Conclusion

We saw how we could implement a Prophet-like model ourselves and fit it to the air passengers dataset. Prophet is an awesome library and a net-positive to the community, but by implementing it ourselves, however, we can take whichever components of it we think are relevant to our problem, customise them, and carry out the Bayesian workflow {cite:p}gelman2020bayesian). Next time you have a time series problem, I hope you will try implementing your own probabilistic model rather than using Prophet as a "black-box" whose arguments are tuneable hyperparameters.

For reference, you might also want to check out:

  • TimeSeeers, a hierarchical Bayesian Time Series model based on Facebooks Prophet, written in PyMC3
  • PM-Prophet, a Pymc3-based universal time series prediction and decomposition library inspired by Facebook Prophet

Authors

References

:::{bibliography} :filter: docname in docnames :::

:::{include} ../page_footer.md :::