Prophet-able Forecasting. Getting started with Prophet... | by Werlindo Mangrobang | Towards Data Science

If you google “time-series forecasting”, most of the first search results you’ll get will involve autoregressive integrated moving average modeling (ARIMA) or exponential smoothing (ETS). And with good reason! There are popular options available for performing applying these time-series forecasting methods, both in R and Python. One of the first forecasting tools I started playing around with are the ARIMA and ETS models in the forecast package in R, led by the influential Rob Hyndman.
One of the most gee-whiz options in forecast is to use auto.arima. The name says it all; it will 'automatically' determine a best-fit ARIMA model, based on the selected information criterion (AIC, BIC, or AICc). Time-series forecasting made easy!
These days, though, I prefer to use Python. And with another quick google search, I spot a potential Python analog. But for this post, I’d like to spend our time getting to know another forecasting Python library: Prophet.
Introduced in 2017, Prophet is a forecasting library developed by Facebook, with implementations in R and Python. It was developed with two goals in mind: First, to create scalable, high-quality forecasts for the business, and second, to have a rigorous methodology behind the scenes, but have its parameter levers be intuitive enough for traditional business analysts to adjust.
For this post we will be doing a brisk stream-of-consciousness-esque quick-start tutorial:
Installing in Python
Setting up the data
Fitting the model and predicting
Inspecting the results
Let’s do this!
If some of the following is a little terse for your taste, I simply followed directions on Prophet’s installation guide. Also, I’m on a Mac, so YMMV with the following if you’re on Windows, etc.
I went to the Installation page on the project’s github.io site and followed the directions for Python. As mentioned there, the library has a major dependency on pystan. On my first attempt, I actually missed the part where it says to pip install pystan first before pip installing fbprophet (the actual name of the Python library). Of course, I DID THE EXACT OPPOSITE, and things were NOT HAPPY.
BUT:
I’m also on the Anaconda distribution of Python, so I was able to eventually get everything working by simply following the Anaconda instructions:
In terminal:
conda install gcc
...and then following any prompts accordingly.
Once that’s done, do the following:install -c conda-forge fbprophet
Phew! That was close. I was afraid this post was going to end right here.
The project site also provides a very clear Quick Start that I ran through to sniff-test that everything worked as intended. I’ll leave it up to you, dear reader, to do the same, and highly encourage it. One can never get enough reps. What I will walk through, though, is another dataset of my choosing, to start getting used to the API.
For this first dataset, we are looking at a dataset on bike share trips in Los Angeles. I pulled down a .csv from Kaggle. Don't tell anyone, but I believe I'm the first person to have ever thought of that. Just kidding! Seriously though, I would have loved to have scraped something, but ran out of time. So Kaggle it is.
You can find the data here.
If you have the Kaggle API installed you can just download directly to your folder of choice by copying the API command:
and then pasting into terminal and running it, like so:kaggle datasets download -d cityofLA/los-angeles-metro-bike-share-trip-data
Another YMMV-type blocker: I then had issues with the downloaded file’s permissions when I tried to unzip it. But I resolved it by:chmod 600 los-angeles-metro-bike-share-trip-data.zip
..which gave me full read/write permissions on the file. Then I was able to unzip it:unzip los-angeles-metro-bike-share-trip-data.zip
OK! Let’s set up the dataframe for running through the Prophet object. Note that the model is expecting very specific column names and types; to quote:
The input to Prophet is always a dataframe with two columns: ds and y. The ds (datestamp) column should be of a format expected by Pandas, ideally YYYY-MM-DD for a date or YYYY-MM-DD HH:MM:SS for a timestamp. The y column must be numeric, and represents the measurement we wish to forecast.
Full Jupyter notebook of all the code is available at this GitHub repository (complete with all my false starts!) but a cleaned up version is as follows:
import pandas as pd          # Dataframes. import plotly_express as px  # Plotting.# Get datasetbikes = pd.read_csv('./data/metro-bike-share-trip-data.csv')# Start time is string, convert to databikes['ds'] = pd.to_datetime(                 bikes['Start Time'].apply(lambda st : st[:10])                                           , format='%Y-%m-%d')# Aggregate by trip start datetrips = bikes.groupby(['ds']).agg(                                 {'Trip ID': 'count'}).reset_index()# Rename columnstrips.columns = ['ds', 'y'] # Column names required by fbprophet API# Plot: reasonability check px.scatter(trips          ,x='ds'          ,y='y'          ,title='LA Daily Bike Share Trips - Jul 16 to Apr 17'          ,labels={'y':'Trips','ds':'Day'})
Next, we’ll run through an example of running a forecast:
Fitting the model
Predicting on our model
First, let’s instantiate our model and fit it on our dataset:
from fbprophet import Prophet     #Importing here for visibility# Create Prophet object and fitm_bikes = Prophet(yearly_seasonality=True                 , weekly_seasonality=True)               #All defaultsm_bikes.fit(trips)
The object Prophet has many parameters that can be set to tune the model. For example, seasonality settings such as daily_seasonality, weekly_seasonality, and yearly_seasonality are just some of the options that can be tuned. For example, I think there might be some weekly and/or yearly patterns for bike-share rentals. For fun, let’s see what happens if we set weekly_seasonality and yearly_seasonalityto True.
Next, we can then perform predictions using the model. the Prophet object has a handy method calledmake_future_dataframe that can create a dataframe with a specified number of future dates, relative to the training data (days is the default periods). For example, below we tack on 60 days after our training data’s last day.
# Create dataframe with appended future datesfuture = m_bikes.make_future_dataframe(periods=60) #Days is defaultfuture.tail()
Once, that dataframe is set up, we can then run predictions on that ‘test’ set:
# Forecast on future dates forecast = m_bikes.predict(future)# Look at prediction and prediction intervalforecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail()
We already got a sneak preview into the predictions by looking at the tail of the forecast dataframe we created. Let’s visualize it though to get the big picture.
It just so happens that our Prophet object also includes a plot method to do just that! Here’s the plot of the fit/forecast (line (y_hat) and shaded area (prediction interval)) versus the actuals (scatter):
# Plot the forecast vs actualsm_bikes.plot(forecast)
In addition, there are plots for the forecast components as well! For example, since we explicitly set weekly_seasonality and yearly_seasonalityto True, there will be component plots specifically for them:
We could definitely use more historical data, but if we take these plots at face value, it appears there is a late summer spike in trips, and then it gradually dips over the fall. Furthermore, during the week, peak riding seemed to happen mid to late weekdays. That might not completely pass the sniff-test of my anecdotal observations if these were Seattle bike-shares, but hey, L.A. is probably a completely different market. The point is though we were able to create some decent forecasts in a short amount of time!
If we had more time to dive in more we could start looking at the aforementioned parameters to further tune the forecasts. These include not only seasonality for different periods, but specific holiday effects, providing specific changepoints for trend (e.g.you don’t have a perfectly linear baseline trend, such as in the example above), accounting for saturation points, and more. Again, details can be found in the documentation, and I would highly encourage reading the white paper to gain a deeper understanding of the underlying methodologies.
That’s all we have time for, I hope this has been useful. Thanks for reading!
Work files here.
Please feel free to reach out! | LinkedIn | GitHub
Sources:
https://facebook.github.io/prophet/
Taylor SJ, Letham B. 2017. Forecasting at scale. PeerJ Preprints 5:e3190v2 https://doi.org/10.7287/peerj.preprints.3190v2