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