Prophet for TimeSeries Forecasting

8 minute read

Facebook’s Prophet for TimeSeries Analysis

Prophet is a library used to analyze and forcast timeseries data. According to Prophet’s homepage: “Prophet is a procedure for forecasting time series data based on an additive model where non-linear trends are fit with yearly, weekly, and daily seasonality, plus holiday effects. It works best with time series that have strong seasonal effects and several seasons of historical data. Prophet is robust to missing data and shifts in the trend, and typically handles outliers well”

This python notebook will provide a quick introduction to the Prophet library.

import numpy as np
import pandas as pd

from fbprophet import Prophet

Load Data

Load the Beer, Wine and Liquor dataset. Prophet requires the data to be in a particular format. It only takes two columns and they must be named ds and y where ds is a pandas datetime object. By default, prophet expects daily data but we can work with other frequencies.

# Load the data, index does not need to be set and dates do not need to be parsed.
df = pd.read_csv('BeerWineLiquor.csv')
df.head()
date beer
0 1/1/1992 1509
1 2/1/1992 1541
2 3/1/1992 1597
3 4/1/1992 1675
4 5/1/1992 1822
# Rename the columns to comply with Prophet's requirements

df.columns = ['ds', 'y']
df.head()
ds y
0 1/1/1992 1509
1 2/1/1992 1541
2 3/1/1992 1597
3 4/1/1992 1675
4 5/1/1992 1822
# Change 'ds' to a pandas datetime object

df['ds'] = pd.to_datetime(df['ds'])
df.head()
ds y
0 1992-01-01 1509
1 1992-02-01 1541
2 1992-03-01 1597
3 1992-04-01 1675
4 1992-05-01 1822
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 324 entries, 0 to 323
Data columns (total 2 columns):
ds    324 non-null datetime64[ns]
y     324 non-null int64
dtypes: datetime64[ns](1), int64(1)
memory usage: 5.1 KB

Create Prophet Model

 # create model

m = Prophet()

# fit model on the entire dataframe

m.fit(df)
INFO:fbprophet:Disabling weekly seasonality. Run prophet with weekly_seasonality=True to override this.
INFO:fbprophet:Disabling daily seasonality. Run prophet with daily_seasonality=True to override this.
<fbprophet.forecaster.Prophet at 0x7fbc80419048>

Forecast into Future

Here we can specify the frequency of the data. In this case we are working with montly data so freq='MS'

# create placeholder dataframe for future predictions

future = m.make_future_dataframe(periods=24, freq = 'MS')  #24 months into the future

future.head()
ds
0 1992-01-01
1 1992-02-01
2 1992-03-01
3 1992-04-01
4 1992-05-01
future.tail()
ds
343 2020-08-01
344 2020-09-01
345 2020-10-01
346 2020-11-01
347 2020-12-01

We can see that when we call future, it returns all the values in the original series plus the 24 new predictions.

# forecast

forecast = m.predict(future)
ds trend yhat_lower yhat_upper trend_lower trend_upper additive_terms additive_terms_lower additive_terms_upper yearly yearly_lower yearly_upper multiplicative_terms multiplicative_terms_lower multiplicative_terms_upper yhat
0 1992-01-01 1765.609137 1149.902720 1466.410036 1765.609137 1765.609137 -461.433071 -461.433071 -461.433071 -461.433071 -461.433071 -461.433071 0.0 0.0 0.0 1304.176066
1 1992-02-01 1768.666905 1180.419186 1493.827910 1768.666905 1768.666905 -426.696951 -426.696951 -426.696951 -426.696951 -426.696951 -426.696951 0.0 0.0 0.0 1341.969954
2 1992-03-01 1771.527398 1435.131609 1742.449773 1771.527398 1771.527398 -178.651299 -178.651299 -178.651299 -178.651299 -178.651299 -178.651299 0.0 0.0 0.0 1592.876098
3 1992-04-01 1774.585166 1423.518804 1742.071067 1774.585166 1774.585166 -196.147147 -196.147147 -196.147147 -196.147147 -196.147147 -196.147147 0.0 0.0 0.0 1578.438018
4 1992-05-01 1777.544296 1644.934947 1979.787556 1777.544296 1777.544296 44.823220 44.823220 44.823220 44.823220 44.823220 44.823220 0.0 0.0 0.0 1822.367516
5 1992-06-01 1780.602064 1635.298880 1963.390959 1780.602064 1780.602064 9.353397 9.353397 9.353397 9.353397 9.353397 9.353397 0.0 0.0 0.0 1789.955461
6 1992-07-01 1783.561194 1743.553772 2074.773511 1783.561194 1783.561194 126.009860 126.009860 126.009860 126.009860 126.009860 126.009860 0.0 0.0 0.0 1909.571054
7 1992-08-01 1786.618962 1660.311149 1978.721968 1786.618962 1786.618962 39.473660 39.473660 39.473660 39.473660 39.473660 39.473660 0.0 0.0 0.0 1826.092622
8 1992-09-01 1789.676731 1480.700161 1817.640762 1789.676731 1789.676731 -133.727623 -133.727623 -133.727623 -133.727623 -133.727623 -133.727623 0.0 0.0 0.0 1655.949107
9 1992-10-01 1792.635861 1577.505206 1916.742344 1792.635861 1792.635861 -43.568316 -43.568316 -43.568316 -43.568316 -43.568316 -43.568316 0.0 0.0 0.0 1749.067544
10 1992-11-01 1795.693629 1733.734259 2048.277041 1795.693629 1795.693629 87.524399 87.524399 87.524399 87.524399 87.524399 87.524399 0.0 0.0 0.0 1883.218028
11 1992-12-01 1798.652759 2707.765926 3025.125676 1798.652759 1798.652759 1070.542133 1070.542133 1070.542133 1070.542133 1070.542133 1070.542133 0.0 0.0 0.0 2869.194892
12 1993-01-01 1801.710526 1197.855819 1521.919002 1801.710526 1801.710526 -446.101695 -446.101695 -446.101695 -446.101695 -446.101695 -446.101695 0.0 0.0 0.0 1355.608831
13 1993-02-01 1804.768294 1153.133293 1465.150706 1804.768294 1804.768294 -490.678227 -490.678227 -490.678227 -490.678227 -490.678227 -490.678227 0.0 0.0 0.0 1314.090067
14 1993-03-01 1807.530149 1450.886668 1768.080193 1807.530149 1807.530149 -193.017532 -193.017532 -193.017532 -193.017532 -193.017532 -193.017532 0.0 0.0 0.0 1614.512616
15 1993-04-01 1810.587916 1436.371916 1767.492210 1810.587916 1810.587916 -202.797703 -202.797703 -202.797703 -202.797703 -202.797703 -202.797703 0.0 0.0 0.0 1607.790213
16 1993-05-01 1813.547046 1700.062450 2010.468249 1813.547046 1813.547046 43.215108 43.215108 43.215108 43.215108 43.215108 43.215108 0.0 0.0 0.0 1856.762154
17 1993-06-01 1816.604814 1663.489399 1993.779644 1816.604814 1816.604814 10.744141 10.744141 10.744141 10.744141 10.744141 10.744141 0.0 0.0 0.0 1827.348955
18 1993-07-01 1819.563944 1797.716444 2117.734809 1819.563944 1819.563944 132.298351 132.298351 132.298351 132.298351 132.298351 132.298351 0.0 0.0 0.0 1951.862295
19 1993-08-01 1822.621711 1691.528954 2022.934720 1822.621711 1822.621711 38.613384 38.613384 38.613384 38.613384 38.613384 38.613384 0.0 0.0 0.0 1861.235095
20 1993-09-01 1825.679479 1541.723483 1871.261652 1825.679479 1825.679479 -128.949728 -128.949728 -128.949728 -128.949728 -128.949728 -128.949728 0.0 0.0 0.0 1696.729751
21 1993-10-01 1828.638609 1617.240901 1953.732334 1828.638609 1828.638609 -46.772013 -46.772013 -46.772013 -46.772013 -46.772013 -46.772013 0.0 0.0 0.0 1781.866595
22 1993-11-01 1831.696376 1727.173523 2058.660750 1831.696376 1831.696376 66.874190 66.874190 66.874190 66.874190 66.874190 66.874190 0.0 0.0 0.0 1898.570566
23 1993-12-01 1834.655506 2754.012265 3073.487686 1834.655506 1834.655506 1087.202109 1087.202109 1087.202109 1087.202109 1087.202109 1087.202109 0.0 0.0 0.0 2921.857615
24 1994-01-01 1837.713274 1220.624127 1559.626594 1837.713274 1837.713274 -451.593922 -451.593922 -451.593922 -451.593922 -451.593922 -451.593922 0.0 0.0 0.0 1386.119351
25 1994-02-01 1840.771041 1207.714535 1545.397667 1840.771041 1840.771041 -469.344011 -469.344011 -469.344011 -469.344011 -469.344011 -469.344011 0.0 0.0 0.0 1371.427030
26 1994-03-01 1843.532896 1476.662169 1802.304315 1843.532896 1843.532896 -207.776241 -207.776241 -207.776241 -207.776241 -207.776241 -207.776241 0.0 0.0 0.0 1635.756655
27 1994-04-01 1846.590663 1472.926540 1803.678509 1846.590663 1846.590663 -209.305874 -209.305874 -209.305874 -209.305874 -209.305874 -209.305874 0.0 0.0 0.0 1637.284789
28 1994-05-01 1849.549793 1734.682415 2056.372995 1849.549793 1849.549793 41.743924 41.743924 41.743924 41.743924 41.743924 41.743924 0.0 0.0 0.0 1891.293716
29 1994-06-01 1852.607561 1709.887338 2022.549671 1852.607561 1852.607561 12.316107 12.316107 12.316107 12.316107 12.316107 12.316107 0.0 0.0 0.0 1864.923667
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
318 2018-07-01 4806.377313 4794.713488 5115.847250 4806.377313 4806.377313 138.521763 138.521763 138.521763 138.521763 138.521763 138.521763 0.0 0.0 0.0 4944.899077
319 2018-08-01 4822.440967 4693.998334 5021.185963 4822.440967 4822.440967 37.665067 37.665067 37.665067 37.665067 37.665067 37.665067 0.0 0.0 0.0 4860.106034
320 2018-09-01 4838.504621 4555.894477 4881.337240 4838.504621 4838.504621 -124.241709 -124.241709 -124.241709 -124.241709 -124.241709 -124.241709 0.0 0.0 0.0 4714.262912
321 2018-10-01 4854.050093 4631.456551 4954.748937 4854.050093 4854.050093 -50.209918 -50.209918 -50.209918 -50.209918 -50.209918 -50.209918 0.0 0.0 0.0 4803.840174
322 2018-11-01 4870.113747 4749.247672 5077.725702 4870.113747 4870.113747 46.587138 46.587138 46.587138 46.587138 46.587138 46.587138 0.0 0.0 0.0 4916.700885
323 2018-12-01 4885.659218 5836.200154 6141.004201 4885.659218 4885.659218 1103.631128 1103.631128 1103.631128 1103.631128 1103.631128 1103.631128 0.0 0.0 0.0 5989.290346
324 2019-01-01 4901.722872 4286.086976 4612.674565 4901.722872 4901.722872 -456.705993 -456.705993 -456.705993 -456.705993 -456.705993 -456.705993 0.0 0.0 0.0 4445.016879
325 2019-02-01 4917.786526 4300.047469 4633.028702 4917.786526 4917.786526 -448.009235 -448.009235 -448.009235 -448.009235 -448.009235 -448.009235 0.0 0.0 0.0 4469.777291
326 2019-03-01 4932.295633 4544.600837 4871.525067 4932.295359 4932.295633 -222.914121 -222.914121 -222.914121 -222.914121 -222.914121 -222.914121 0.0 0.0 0.0 4709.381512
327 2019-04-01 4948.359287 4577.479311 4901.958065 4948.220479 4948.457766 -215.660891 -215.660891 -215.660891 -215.660891 -215.660891 -215.660891 0.0 0.0 0.0 4732.698396
328 2019-05-01 4963.904758 4841.252176 5161.292248 4963.510636 4964.381168 40.411482 40.411482 40.411482 40.411482 40.411482 40.411482 0.0 0.0 0.0 5004.316240
329 2019-06-01 4979.968412 4836.711506 5159.222845 4979.169708 4980.848209 14.065469 14.065469 14.065469 14.065469 14.065469 14.065469 0.0 0.0 0.0 4994.033881
330 2019-07-01 4995.513884 4974.094211 5306.556883 4994.165743 4996.762176 144.671808 144.671808 144.671808 144.671808 144.671808 144.671808 0.0 0.0 0.0 5140.185692
331 2019-08-01 5011.577538 4884.601425 5209.666401 5009.559512 5013.365085 36.627977 36.627977 36.627977 36.627977 36.627977 36.627977 0.0 0.0 0.0 5048.205515
332 2019-09-01 5027.641192 4743.204675 5072.656517 5024.915575 5029.973688 -119.607212 -119.607212 -119.607212 -119.607212 -119.607212 -119.607212 0.0 0.0 0.0 4908.033980
333 2019-10-01 5043.186663 4810.797521 5163.259815 5039.794038 5046.018956 -53.874874 -53.874874 -53.874874 -53.874874 -53.874874 -53.874874 0.0 0.0 0.0 4989.311789
334 2019-11-01 5059.250317 4928.104855 5246.653307 5055.235973 5062.553975 26.677053 26.677053 26.677053 26.677053 26.677053 26.677053 0.0 0.0 0.0 5085.927371
335 2019-12-01 5074.795789 6031.243339 6361.544758 5070.094258 5078.928058 1119.819177 1119.819177 1119.819177 1119.819177 1119.819177 1119.819177 0.0 0.0 0.0 6194.614966
336 2020-01-01 5090.859443 4459.291007 4792.737340 5085.520962 5095.783698 -461.433071 -461.433071 -461.433071 -461.433071 -461.433071 -461.433071 0.0 0.0 0.0 4629.426372
337 2020-02-01 5106.923097 4511.518627 4835.497542 5100.893269 5112.554201 -426.696951 -426.696951 -426.696951 -426.696951 -426.696951 -426.696951 0.0 0.0 0.0 4680.226146
338 2020-03-01 5121.950386 4772.153906 5109.743878 5115.064403 5128.198273 -178.651299 -178.651299 -178.651299 -178.651299 -178.651299 -178.651299 0.0 0.0 0.0 4943.299086
339 2020-04-01 5138.014040 4769.322567 5101.754255 5130.352294 5145.071656 -196.147147 -196.147147 -196.147147 -196.147147 -196.147147 -196.147147 0.0 0.0 0.0 4941.866893
340 2020-05-01 5153.559511 5032.043549 5357.118499 5145.136362 5161.521044 44.823220 44.823220 44.823220 44.823220 44.823220 44.823220 0.0 0.0 0.0 5198.382732
341 2020-06-01 5169.623165 5014.939445 5339.767766 5160.249669 5178.432192 9.353397 9.353397 9.353397 9.353397 9.353397 9.353397 0.0 0.0 0.0 5178.976562
342 2020-07-01 5185.168637 5153.127728 5468.195021 5174.969708 5194.711338 126.009860 126.009860 126.009860 126.009860 126.009860 126.009860 0.0 0.0 0.0 5311.178497
343 2020-08-01 5201.232291 5075.152631 5402.431645 5190.100935 5211.917374 39.473660 39.473660 39.473660 39.473660 39.473660 39.473660 0.0 0.0 0.0 5240.705951
344 2020-09-01 5217.295945 4921.693533 5236.449879 5205.091958 5229.115313 -133.727623 -133.727623 -133.727623 -133.727623 -133.727623 -133.727623 0.0 0.0 0.0 5083.568322
345 2020-10-01 5232.841416 5023.463492 5348.619770 5219.448873 5245.289862 -43.568316 -43.568316 -43.568316 -43.568316 -43.568316 -43.568316 0.0 0.0 0.0 5189.273100
346 2020-11-01 5248.905070 5175.789029 5494.137840 5234.446406 5262.375734 87.524399 87.524399 87.524399 87.524399 87.524399 87.524399 0.0 0.0 0.0 5336.429469
347 2020-12-01 5264.450542 6178.372861 6494.823661 5249.011609 5278.889130 1070.542133 1070.542133 1070.542133 1070.542133 1070.542133 1070.542133 0.0 0.0 0.0 6334.992675

When we call forecast it returns a lot of information. However, we are mainly interested in the actual prediction y_hat as well as the upper and lower bounds/confidence intervals yhat_lower and yhat_upper

forecast.columns
Index(['ds', 'trend', 'yhat_lower', 'yhat_upper', 'trend_lower', 'trend_upper',
       'additive_terms', 'additive_terms_lower', 'additive_terms_upper',
       'yearly', 'yearly_lower', 'yearly_upper', 'multiplicative_terms',
       'multiplicative_terms_lower', 'multiplicative_terms_upper', 'yhat'],
      dtype='object')

We can select the last 12 datapoints from the forecast to see what the predictions are.

# select variables of interest

forecast[['ds', 'yhat_lower', 'yhat_upper', 'yhat']].tail(12)
ds yhat_lower yhat_upper yhat
336 2020-01-01 4459.291007 4792.737340 4629.426372
337 2020-02-01 4511.518627 4835.497542 4680.226146
338 2020-03-01 4772.153906 5109.743878 4943.299086
339 2020-04-01 4769.322567 5101.754255 4941.866893
340 2020-05-01 5032.043549 5357.118499 5198.382732
341 2020-06-01 5014.939445 5339.767766 5178.976562
342 2020-07-01 5153.127728 5468.195021 5311.178497
343 2020-08-01 5075.152631 5402.431645 5240.705951
344 2020-09-01 4921.693533 5236.449879 5083.568322
345 2020-10-01 5023.463492 5348.619770 5189.273100
346 2020-11-01 5175.789029 5494.137840 5336.429469
347 2020-12-01 6178.372861 6494.823661 6334.992675

Plot Results

Using Prophet’s built-in plotting tools to visualize the results.

prophet_graph_1

We can execute the code below to zoom into a particular period of time so we can better see the results.


# Zoom-in to 2014 onwards
import matplotlib.pyplot as plt
%matplotlib inline
m.plot(forecast)
plt.xlim('2014-01-01','2021-01-01')

Plot components

We can also separate and plot the individual components of the graph.

m.plot_components(forecast);

Tags:

Updated: