Get the "Applied Data Science Edge"!

The ViralML School

Fundamental Market Analysis with Python - Find Your Own Answers On What Is Going on in the Financial Markets

Web Work

Python Web Work - Prototyping Guide for Maker

Use HTML5 Templates, Serve Dynamic Content, Build Machine Learning Web Apps, Grow Audiences & Conquer the World!

Hot off the Press!

The Little Book of Fundamental Market Indicators

My New Book: "The Little Book of Fundamental Analysis: Hands-On Market Analysis with Python" is Out!

Forecasting Demand, Finding Sales Data - Facebook Prophet, Google Trends & Python

Introduction

Let's talk about forecasting demand, this is as old as money and commerce. Rainy season, you stock up on umbrellas; winter, winter coats, etc. I'll walk you through a simple example using open-source FBProphet in Python, one of the most powerful forecasting engines and also one of the easiest to use (once you manage to install it).



If you liked it, please share it:

Code

Forecasting Demand - Quick Intro to FBProphet
In [124]:
from IPython.display import Image
Image(filename='Forecasting-Demand.png')
Out[124]:
In [125]:
# Image(filename='fb-prophet.png')

Forecasting Online Interest and Demand

Let's talk about forecasting demand, this is as old as money and commerce. Rainy seasons you stock up on umbrellas, for winter, winter coats, etc. It is also critical today, where so many stores around the world are closed due to covid19 and want an online presence, a virtual store to mirror Amazon and the likes. And most products aren't as straightforward as selling umbrellas.

I'll walk you through a simple example using open-source FBProphet in Python, one of the most powerful forecasting engines and also one of the easiest to use (once you manage to install it). I'll also show you external data sources that work great as proxy values to forecast demand when you want to understand products you don't carry or you don't have enough data stored.

To properly forecast demand you need enough data to teach a model the different cycles and season around that product, preferably a few of those cycles. FBProphet recommends 3 years of data so the model can understand the different holidays, peak sales, low sales, etc.

Let me show you an example using anonymized data from a Kaggle competition the "Store Item Demand Forecasting Challenge"

Open Source FBProphet

"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"

"It works best with time series that have strong seasonal effects and several seasons of historical data."

"Prophet is used in many applications across Facebook for producing reliable forecasts for planning and goal setting. We’ve found it to perform better than any other approach in the majority of cases."

FBProphet Quick Start Guide

https://facebook.github.io/prophet/docs/quick_start.html

Installing FB Prophet:

!pip3 install fbprophet --user


!pip3 install holidays==0.9.12

Kaggle data

https://www.kaggle.com/c/demand-forecasting-kernels-only/data

In [94]:
import time
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import statsmodels.api as sm
import io, base64, os, json, re, glob
import datetime
from datetime import timedelta
import pandas as pd
import pydata_google_auth
import numpy as np

from fbprophet import Prophet
import statsmodels.api as sm
In [102]:
df_raw = pd.read_csv('demand-forecasting-kernels-only/train.csv', 
                     low_memory=False, 
                     parse_dates=['date'], 
                     index_col=['date'])
In [103]:
df_raw = df_raw.sort_values('date', ascending=True)
print(df_raw.shape)
df_raw.head()
(913000, 3)
Out[103]:
store item sales
date
2013-01-01 1 1 13
2013-01-01 7 12 26
2013-01-01 7 46 27
2013-01-01 8 12 54
2013-01-01 9 12 35

Store 1 - All Sales

In [104]:
plt.subplots(1, figsize = (16, 5))
plt.grid()
plt.title('Store 1 - All Sales')
for item in set(df_raw[df_raw['store'] == 1]['item']):
    plt.plot(df_raw[(df_raw['store'] == 1) & 
                    (df_raw['item'] == item)]['sales'].rolling(window=50).mean())

Item 1 All Stores

In [105]:
plt.subplots(1, figsize = (16, 5))
plt.grid()
plt.title('Item 1 - Sales per Store')
for store in set(df_raw[df_raw['item'] == 1]['store']):
    plt.plot(df_raw[(df_raw['item'] == 1) & 
                    (df_raw['store'] == store)]['sales']
             .rolling(window=50).mean())

Predicting the Future Facebook's FBProphet

In [106]:
# preparing the data into FBP format:
train_dataset = df_raw[(df_raw['item'] == 1) & df_raw['store'] == 1] 
train_dataset.reset_index(level=0, inplace=True)
train_dataset = train_dataset[['date', 'sales']]
train_dataset.columns = ["ds", "y"]

train_dataset = train_dataset.sample(5000)
prophet_basic = Prophet()
prophet_basic.fit(train_dataset)
INFO:fbprophet:Disabling daily seasonality. Run prophet with daily_seasonality=True to override this.
Out[106]:
<fbprophet.forecaster.Prophet at 0x1307fa898>
In [107]:
future= prophet_basic.make_future_dataframe(periods=365)
future
Out[107]:
ds
0 2013-01-01
1 2013-01-01
2 2013-01-02
3 2013-01-02
4 2013-01-03
... ...
5360 2018-12-27
5361 2018-12-28
5362 2018-12-29
5363 2018-12-30
5364 2018-12-31

5365 rows × 1 columns

In [108]:
forecast=prophet_basic.predict(future)

#Plotting the predicted data
fig1 =prophet_basic.plot(forecast)
In [109]:
fig1 = prophet_basic.plot_components(forecast)
In [44]:
from fbprophet.plot import add_changepoints_to_plot
fig = prophet_basic.plot(forecast)
a = add_changepoints_to_plot(fig.gca(), prophet_basic, forecast)

What to Do If You Don't Have Years of Data or You Are Trying out a New Product?

In [121]:
# Google Trends - Vitamin D
# https://trends.google.com/trends/explore?date=today%205-y&geo=US&q=vitamin%20d
df_vitamins = pd.read_csv('vitamin_d.csv')
df_vitamins['ds'] = pd.to_datetime(df_vitamins['ds'])
df_vitamins = df_vitamins.sort_values('ds', ascending=True)
print(df_raw.shape)
df_vitamins.head()
(913000, 3)
Out[121]:
ds y
0 2015-04-05 71
1 2015-04-12 63
2 2015-04-19 67
3 2015-04-26 58
4 2015-05-03 63
In [120]:
train_dataset = df_vitamins.copy()
prophet_basic = Prophet()
prophet_basic.fit(train_dataset)
future= prophet_basic.make_future_dataframe(periods=365)
future.tail(100)
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.
Out[120]:
ds
0 2015-04-05
1 2015-04-12
2 2015-04-19
3 2015-04-26
4 2015-05-03
... ...
95 2017-01-29
96 2017-02-05
97 2017-02-12
98 2017-02-19
99 2017-02-26

100 rows × 1 columns

In [113]:
forecast=prophet_basic.predict(future)
#Plotting the predicted data
fig1 =prophet_basic.plot(forecast)
In [114]:
fig1 = prophet_basic.plot_components(forecast)
In [122]:
# access predictions
forecast.tail()
Out[122]:
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
621 2021-03-25 73.566303 81.666490 91.107874 73.197328 73.986529 12.813260 12.813260 12.813260 12.813260 12.813260 12.813260 0.0 0.0 0.0 86.379563
622 2021-03-26 73.576596 81.729395 91.031679 73.206594 73.997648 12.722826 12.722826 12.722826 12.722826 12.722826 12.722826 0.0 0.0 0.0 86.299422
623 2021-03-27 73.586889 81.095189 90.809882 73.215860 74.010042 12.576597 12.576597 12.576597 12.576597 12.576597 12.576597 0.0 0.0 0.0 86.163487
624 2021-03-28 73.597182 81.211549 91.006258 73.225126 74.022225 12.373949 12.373949 12.373949 12.373949 12.373949 12.373949 0.0 0.0 0.0 85.971131
625 2021-03-29 73.607476 81.001951 90.919125 73.234392 74.034277 12.115549 12.115549 12.115549 12.115549 12.115549 12.115549 0.0 0.0 0.0 85.723025

Show Notes

(pardon typos and formatting -
these are the notes I use to make the videos)

Let's talk about forecasting demand, this is as old as money and commerce. Rainy season, you stock up on umbrellas; winter, winter coats, etc. I'll walk you through a simple example using open-source FBProphet in Python, one of the most powerful forecasting engines and also one of the easiest to use (once you manage to install it).