Kenbwire / Jun 21 2019
Saturating Forecasts
Saturating Growth
import pandas as pd from fbprophet import Prophet from fbprophet.plot import plot_plotly import plotly.offline as py py.init_notebook_mode() url = "https://nextjournal.com/data/QmVbsLznbDsfbVnZBxR4JsFREXbvv63LkNytvk1fTxe9vu?content-type=text%2Fcsv&filename=example_wp_log_R.csv" df = pd.read_csv(url) df['cap'] = 8.5 m = Prophet(growth='logistic') m.fit(df) future = m.make_future_dataframe(periods=1826) future['cap'] = 8.5 fcst = m.predict(future) fig = m.plot(fcst)
Saturating Minimum
df['y'] = 10 - df['y'] df['cap'] = 6 df['floor'] = 1.5 future['cap'] = 6 future['floor'] = 1.5 m = Prophet(growth='logistic') m.fit(df) fcst = m.predict(future) fig = m.plot(fcst)
Trend Changepoints
Automatic changepoint detection in Prophet
from fbprophet.plot import add_changepoints_to_plot forecast = fcst fig = m.plot(forecast) a = add_changepoints_to_plot(fig.gca(), m, forecast)
Adjusting trend flexibility
m = Prophet(changepoint_prior_scale=0.5) forecast = m.fit(df).predict(future) fig = m.plot(forecast)
Decreasing it will make the trend less flexible:
m = Prophet(changepoint_prior_scale=0.001) forecast = m.fit(df).predict(future) fig = m.plot(forecast)
Specifying the locations of the changepoints
m = Prophet(changepoints=['2014-01-01']) forecast = m.fit(df).predict(future) fig = m.plot(forecast)
Seasonality, Holiday Effects, And Regressors
Modeling Holidays and Special Events
playoffs = pd.DataFrame({ 'holiday': 'playoff', 'ds': pd.to_datetime(['2008-01-13', '2009-01-03', '2010-01-16', '2010-01-24', '2010-02-07', '2011-01-08', '2013-01-12', '2014-01-12', '2014-01-19', '2014-02-02', '2015-01-11', '2016-01-17', '2016-01-24', '2016-02-07']), 'lower_window': 0, 'upper_window': 1, }) superbowls = pd.DataFrame({ 'holiday': 'superbowl', 'ds': pd.to_datetime(['2010-02-07', '2014-02-02', '2016-02-07']), 'lower_window': 0, 'upper_window': 1, }) holidays = pd.concat((playoffs, superbowls)) m = Prophet(holidays=holidays) forecast = m.fit(df).predict(future) forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][ ['ds', 'playoff', 'superbowl']][-10:]
ds | playoff | superbowl | |
---|---|---|---|
2168 | 2014-02-02 | -0.041448910794072 | -0.061800063179915085 |
2169 | 2014-02-03 | -0.02677602860523033 | 0.031581560092876944 |
2510 | 2015-01-11 | -0.041448910794072 | 0.0 |
2511 | 2015-01-12 | -0.02677602860523033 | 0.0 |
2879 | 2016-01-17 | -0.041448910794072 | 0.0 |
2880 | 2016-01-18 | -0.02677602860523033 | 0.0 |
2886 | 2016-01-24 | -0.041448910794072 | 0.0 |
2887 | 2016-01-25 | -0.02677602860523033 | 0.0 |
2900 | 2016-02-07 | -0.041448910794072 | -0.061800063179915085 |
2901 | 2016-02-08 | -0.02677602860523033 | 0.031581560092876944 |
10 items
fig = m.plot_components(forecast)
Built-in Country Holidays
m = Prophet(holidays=holidays) m.add_country_holidays(country_name='US') m.fit(df) m.train_holiday_names
forecast = m.predict(future) fig = m.plot_components(forecast)
Fourier Order for Seasonalities
from fbprophet.plot import plot_yearly m = Prophet().fit(df) a = plot_yearly(m)
m = Prophet(yearly_seasonality=20).fit(df) a = plot_yearly(m)
Specifying Custom Seasonalities
m = Prophet(weekly_seasonality=False) m.add_seasonality(name='monthly', period=30.5, fourier_order=5) forecast = m.fit(df).predict(future) fig = m.plot_components(forecast)
Seasonalities that depend on other factors
def is_nfl_season(ds): date = pd.to_datetime(ds) return (date.month > 8 or date.month < 2) df['on_season'] = df['ds'].apply(is_nfl_season) df['off_season'] = ~df['ds'].apply(is_nfl_season) m = Prophet(weekly_seasonality=False) m.add_seasonality(name='weekly_on_season', period=7, fourier_order=3, condition_name='on_season') m.add_seasonality(name='weekly_off_season', period=7, fourier_order=3, condition_name='off_season') future['on_season'] = future['ds'].apply(is_nfl_season) future['off_season'] = ~future['ds'].apply(is_nfl_season) forecast = m.fit(df).predict(future) fig = m.plot_components(forecast)
Prior scale for holidays and seasonality
m = Prophet(holidays=holidays, holidays_prior_scale=0.05).fit(df) forecast = m.predict(future) forecast[(forecast['playoff'] + forecast['superbowl']).abs() > 0][ ['ds', 'playoff', 'superbowl']][-10:]
m = Prophet() m.add_seasonality( name='weekly', period=7, fourier_order=3, prior_scale=0.1)
<fbprophet.fo...x7fae7e917e10>
Additional regressors
def nfl_sunday(ds): date = pd.to_datetime(ds) if date.weekday() == 6 and (date.month > 8 or date.month < 2): return 1 else: return 0 df['nfl_sunday'] = df['ds'].apply(nfl_sunday) m = Prophet() m.add_regressor('nfl_sunday') m.fit(df) future['nfl_sunday'] = future['ds'].apply(nfl_sunday) forecast = m.predict(future) fig = m.plot_components(forecast)
Multiplicative Seasonality
url = "https://nextjournal.com/data/QmNkm2vmD7CDajrKYqDkusji6aR7bhETyjvZXoJ15Vq194?content-type=text%2Fcsv&filename=example_air_passengers.csv" df = pd.read_csv(url) m = Prophet() m.fit(df) future = m.make_future_dataframe(50, freq='MS') forecast = m.predict(future) fig = m.plot(forecast)
m = Prophet(seasonality_mode='multiplicative') m.fit(df) forecast = m.predict(future) fig = m.plot(forecast)
fig = m.plot_components(forecast)
m = Prophet(seasonality_mode='multiplicative') m.add_seasonality('quarterly', period=91.25, fourier_order=8, mode='additive') m.add_regressor('regressor', mode='additive')
<fbprophet.fo...x7fae7dea52b0>
Uncertainty Intervals
Uncertainty in the trend
forecast = Prophet(interval_width=0.95).fit(df).predict(future)
Uncertainty in seasonality
m = Prophet(mcmc_samples=300) forecast = m.fit(df).predict(future)
fig = m.plot_components(forecast)
Outliers
url = "https://nextjournal.com/data/QmasyK2jtb8dyCebuQQaDMKmFtsb9wQHkUCqBSGdAfs3rM?content-type=text%2Fcsv&filename=example_wp_log_R_outliers1.csv" df = pd.read_csv(url) m = Prophet() m.fit(df) future = m.make_future_dataframe(periods=1096) forecast = m.predict(future) fig = m.plot(forecast)
df.loc[(df['ds'] > '2010-01-01') & (df['ds'] < '2011-01-01'), 'y'] = None model = Prophet().fit(df) fig = model.plot(model.predict(future))
url = "https://nextjournal.com/data/QmPYAGdQsQyi5QkuzUWi4x4u3Bu82ew8uD3ANhEUhp7tDb?content-type=text%2Fcsv&filename=example_wp_log_R_outliers2.csv" df = pd.read_csv(url) m = Prophet() m.fit(df) future = m.make_future_dataframe(periods=1096) forecast = m.predict(future) fig = m.plot(forecast)
df.loc[(df['ds'] > '2015-06-01') & (df['ds'] < '2015-06-30'), 'y'] = None m = Prophet().fit(df) fig = m.plot(m.predict(future))
Non-Daily Data
Sub-daily data
url = "https://nextjournal.com/data/QmbKkFrpdLSFFXoMg7LXX7FHXv5jPRY6ohurkzpHz9JXLM?content-type=text%2Fcsv&filename=example_yosemite_temps.csv" df = pd.read_csv(url) m = Prophet(changepoint_prior_scale=0.01).fit(df) future = m.make_future_dataframe(periods=300, freq='H') fcst = m.predict(future) fig = m.plot(fcst)
fig = m.plot_components(fcst)
Data with regular gaps
df2 = df.copy() df2['ds'] = pd.to_datetime(df2['ds']) df2 = df2[df2['ds'].dt.hour < 6] m = Prophet().fit(df2) future = m.make_future_dataframe(periods=300, freq='H') fcst = m.predict(future) fig = m.plot(fcst)
future2 = future.copy() future2 = future2[future2['ds'].dt.hour < 6] fcst = m.predict(future2) fig = m.plot(fcst)
Monthly data
url = "https://nextjournal.com/data/QmVAEmz1VSSESVw6aJsskdSacEPJV2m4BvJNoUCWzcApu1?content-type=text%2Fcsv&filename=example_retail_sales.csv" df = pd.read_csv(url) m = Prophet(seasonality_mode='multiplicative').fit(df) future = m.make_future_dataframe(periods=3652) fcst = m.predict(future) fig = m.plot(fcst)
m = Prophet(seasonality_mode='multiplicative', mcmc_samples=300).fit(df) fcst = m.predict(future) fig = m.plot_components(fcst)
future = m.make_future_dataframe(periods=120, freq='M') fcst = m.predict(future) fig = m.plot(fcst)
Diagnostics
from fbprophet.diagnostics import cross_validation df_cv = cross_validation(m, initial='730 days', period='180 days', horizon = '365 days') df_cv.head()