Understanding Time Series with Facebook’s Prophet
By: Uday Bhaskar
Tags: Data Science, Timeseries Forecasting, Time Series Forecasting, Time Series Analysis

It has always been a difficult task to predict the future and analyze the upcoming events until data comes into the picture. yes, data is a powerful resource to predict the future and Time Series forecasting is an effective way to predict the future values based on the observed values.

There are many Time Series forecasting models:

Exponential Smoothing Holt Winter Forecasting AR, ARMA ARIMA, SARIMA GARCH

Since I started studying the time series forecasting models and their applications I came across a model “Prophet” which has been developed by the Facebook team which can be used by the people who have less domain knowledge and Prophet can produce accurate results in default settings.it is an open-source available in both R and Python.

The organizations are facing difficulty in finding the Analysts who can produce high-quality forecasts because forecasting is a specialized data science skill requiring substantial experience. Prophet is a time series model that can address this problem and produce better results with slight changes in the model. I won’t dive much deep into the math behind this model but we try to find the best results by using this model on a simple dataset

The Prophet Forecasting Model:

This model has three main components: Trend,Seasonality, and Holidays.

g(t): piecewise linear or logistic growth curve for modelling non-periodic changes in time series.

s(t): periodic changes(weekly/yearly)

h(t): effect of holidays

εt: error term accounts for any unusual changes not accommodated by the model

Loading the data:

The below data set is the shampoo sales over three years

import pandas as pd

import numpy as np

import matplotlib.pyplot as plt

import seaborn as sns

from fbprophet import Prophet

from fbprophet.diagnostics import performance_metrics df = pd.read_csv("C:\\Users\\Dell\\Desktop\\sales-of-shampoo-over-a-three-ye.csv")

# reading the first five rows

df.head()

output

Prophet requires the date column to be labeled “ds” and the target column to be labeled “y”

df_shampoo_orig = pd.read_csv(‘C:\\Users\\Dell\\Desktop\\sales-of-shampoo-over-a-three-ye.csv’,

nrows=36,

skiprows = 1,

names = [‘ds’, ‘y’],

parse_dates = True )

df = df_shampoo_orig

df.head()

output:

Let's get the ds column into date-time format

df['ds'] = df.ds.apply(lambda x: "201"+x)

df.head()

output:

tseries.offset.MonthEnd(0)

This next cell uses the awesome tseries.offset.MonthEnd(0) method to make the day of the month the final day. This is necessary for Prophet to make the predictions we need at the correctly spaced monthly intervals.

df['ds']=pd.to_datetime(df['ds'])+pd.tseries.offsets.MonthEnd(0) df.head()

output:

Prophet forecast: we need to make some observations for future predictions. let us make 12 months of predictions.

train = df[:24]

train.tail() test = df[24:]

output:

let's train the model:

m = Prophet(weekly_seasonality=False, daily_seasonality=False, n_changepoints=2)

m.add_seasonality(name='yearly', period=12, fourier_order=1)



m.fit(train)

let's make the future data frame and make the predictions. we need to pass freq= m because we want to make monthly predictions

future = m.make_future_dataframe(periods=12, freq='m')

forecast = m.predict(future2)

a = forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']]

prophet_pred = pd.DataFrame({"Date":a[-12:]['ds'],"pred":a[-12:]["yhat"]})

prophet_pred=prophet_pred.set_index("Date")

prophet_pred.index.freq = "M"test["prophet_predictions"] = prophet_pred['pred'].values

test

output:

let's make at a plot

figure = m.plot(forecast)

output:

The dots are the actual data points. The line through the dots is predicted values. The shared area represents the uncertainty intervals.

lets plot trend and seasonality

fig_decompose = m.plot_components(forecast)

output:

calculating the error for the above predictions:

a = forecast[[‘ds’, ‘yhat’, ‘yhat_lower’, ‘yhat_upper’]]

prophet_pred = pd.DataFrame({“Date”:a[-12:][‘ds’],”pred”:a[-12:][“yhat”]})

prophet_pred=prophet_pred.set_index(“Date”)

prophet_pred.index.freq = “M”

test["prophet_predictions"] = prophet_pred['pred'].values # function to calculate the RMSE

def rmse(predictions, targets): return np.sqrt(((predictions - targets) ** 2).mean()) # calculating RMSE and MSE prophet_rmse_error = rmse(test['y'], test["prophet_predictions"])

prophet_mse_error = prophet_rmse_error**2

mean_value = df['y'].mean() print(f'MSE Error: {prophet_mse_error}

RMSE Error: {prophet_rmse_error}

Mean: {mean_value}')

output:

Now we will try to change the Fourier order from 1 to 5 and let's see what happens, everything is the same except this

m1 = Prophet(weekly_seasonality=False, daily_seasonality=False, n_changepoints=2)

m1.add_seasonality(name=’yearly’, period=12, fourier_order=5)

m1.fit(train)

future1 = m1.make_future_dataframe(periods=12, freq=’M’)

forecast1 = m1.predict(future) #testing our predictions b = forecast1[['ds', 'yhat', 'yhat_lower', 'yhat_upper']]

prophet_pred1 = pd.DataFrame({"Date":b[-12:]['ds'],"pred":b[-12:]["yhat"]})

prophet_pred1=prophet_pred1.set_index("Date")

prophet_pred.index.freq = "M"

we will calculate the error for Fourier order = 5 and lets us see whether the error decreases or increases

prophet_rmse_error = rmse(test[‘y’], test[“prophet_predictions”])

prophet_mse_error = prophet_rmse_error**2

mean_value = df[‘y’].mean()

print(f’MSE Error: {prophet_mse_error}

RMSE Error: {prophet_rmse_error}

Mean: {mean_value}’)

output:

In this case, our error has been increased and we can play with parameters to get better results, Here I just tried to give an overview about prophet model as the parameters are easy to adjust to better results rather than time series models which require a bit domain knowledge

I will mention the sources from where I learned you can get better insight about this model

Regards,

uday.