Skip to main content

Time series forecasting with Prophet

In this example we'll train and deploy a Facebook Prophet forecasting model. We'll use the forecaster of daily pageviews for the Peyton Manning Wikipedia page that Prophet walks through in their quick start guide.

Building the model

First, import and log in to Modelbit:

import modelbit

mb = modelbit.login()

To train the model, download the dataset, instantiate a Prophet object, and call fit on that object in exactly the same way as in the Prophet documentation:

from prophet import Prophet
import pandas as pd
training_df = pd.read_csv('https://raw.githubusercontent.com/facebook/prophet/main/examples/example_wp_log_peyton_manning.csv')
prophet_model = Prophet()
prophet_model.fit(training_df)

Deploying a model for single inferences

You can deploy this model to Modelbit so that it will return a single inference for a single date. This is suitable for online use cases such as serving inferences in your website.

Building and deploying the Python

To make the model ready for deployment to Modelbit, we'll write a deploy function that will be called at inference time. Notice that we don't specify a type for the date_to_forecast parameter, so that the SQL function Modelbit creates will expect a variant type:

def prophet_forecaster(date_to_forecast) -> float:
df = pd.DataFrame({
'ds': [date_to_forecast]
})
return prophet_model.predict(df)['yhat'][0]

Prophet puts its forecast in the yhat field in the resulting DataFrame, so that's what we return. To return more information, e.g. error bars, return a Python dictionary:

def detailed_prophet_forecaster(date_to_forecast) -> dict:
df = pd.DataFrame({
'ds': [date_to_forecast]
})

result_df = prophet_model.predict(df)
return {
'prediction': result_df['yhat'][0],
'upper_bound': result_df['yhat_upper'][0],
'lower_bound': result_df['yhat_lower'][0]
}

We can test this function locally:

prophet_forecaster('2022-11-16')

In This call returns 5.29204606331416.

To deploy to Modelbit, simply call mb.deploy:

mb.deploy(prophet_forecaster, python_version="3.9", python_packages=["prophet==1.1.1"])

Make sure python_version and python_packages match your current Python version and Prophet package version! You can omit them if the required versions are in your Modelbit default environment. When in doubt, they are always safe to leave in.

Click the link that Modelbit outputs to see your model running in production!

Getting single inferences in production

To call your model from REST, simply pass a string:

curl -s -XPOST "https://<your-workspace-url>/v1/prophet_forecaster/latest" -d '{"data": "2022-11-16"}' | json_pp

You should see output like:

{
"data": [[0, 5.29204606331416]]
}

To call your model from Snowflake or Redshift, simply cast a date to variant, e.g. in Snowflake:

select my_schema.prophet_forecaster_latest(current_date()::variant);

If you have a table full of dates you want forecasts for, you can write SQL like:

update my_pageviews set projected_pageviews = my_schema.prophet_forecaster_latest(date_column::variant);

Your warehouse and Modelbit will automatically handle the batching, and a batch of predictions from your prophet_forecaster will be written back to the my_pageviews table.

Deploying a model for batch inference

You can also deploy the model in such a way that the model scores an entire batch at once. This is suitable for batch use cases, such as building an entire table of predictions in your data warehouse.

Building and deploying the Python

We'll build a Python deploy function that will be called at inference time. This function will receive a DataFrame as input, and should return a DataFrame or other Python iterable as output.

In the case of Prophet, the DataFrame will contain the dates we expect to get inferences for:

def prophet_batch_forecaster(dates_df: pandas.DataFrame) -> pandas.DataFrame:
"""
Batch Peyton Manning Wikipedia Pageviews Prophet Forecaster
"""

return prophet_model.predict(dates_df)[['yhat', 'yhat_upper', 'yhat_lower']]

We will now deploy this function and its dependencies to Modelbit, taking advantage of Modelbit's DataFrame Mode for this batch use case:

mb.deploy(prophet_batch_forecaster,
dataframe_mode = True,
example_dataframe = training_df[['ds']])

Getting batch inferences from SQL

As with the single inference example, Snowflake will handle the batching for you. We will change the call slightly, passing a SQL object that then gets converted into a DataFrame for your Python function:

update my_pageviews set projected_pageviews = my_schema.prophet_forecaster_latest({'ds': date_column});

You can also generate the date fields in SQL to get a batch of predictions for them all at once. This is ideal for building a table of dates and inferences, i.e. in a dbt model. In Snowflake:

with dates as (
select
-- Every week starting at the end of January 2021
dateadd(week, row_number() over (order by null), date('2021-01-24')) as date
from
table(generator(rowcount => 153))
)
select my_schema.prophet_forecaster_latest({
'ds': date
})
from dates