Prophet for TimeSeries Forecasting
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.
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);