Demand Forecasting and Inventory Management in Retail Store — SARIMA Model

Nivedha
4 min readDec 29, 2023

--

The retail store handles stock on a large scale daily, making monitoring and managing the inventory more tedious. Traditional retail store inventory management is a cumbersome methodology with inefficient monitoring, tracking and management. This brings in the need for a robust digitized inventory management system that seamlessly performs retail store stock analytics to achieve less inventory on hand and more stocks on sale with less manual labor.

This article shows how SARIMA, a time series machine learning model can be used to efficiently perform retail store stock inventory analysis and calculate the inventory parameter needed to cater to the needs of customers over time benefitting the retail store with maximum profit.

Source: Google Images

Dataset

To begin with, download the following dataset. This dataset has historical record of a specific product which includes information on the date, product demand and current inventory levels.

Code

The Python code for performing the demand forecasting and inventory management is as below.

import pandas as pd
import numpy as np
import plotly.express as px
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf
import matplotlib.pyplot as plt
from statsmodels.tsa.statespace.sarimax import SARIMAX

data = pd.read_csv("demand_inventory.csv")
print(data.head())

data = data.drop(columns=['Unnamed: 0'])

fig_demand = px.line(data, x='Date', y='Demand', title='Demand Over Time')
fig_demand.show()

fig_inventory = px.line(data, x='Date', y='Inventory', title='Inventory Over Time')
fig_inventory.show()

data['Date'] = pd.to_datetime(data['Date'], format='%Y/%m/%d')
time_series = data.set_index('Date')['Demand']

differenced_series = time_series.diff().dropna()

# Plot ACF and PACF of differenced time series
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
plot_acf(differenced_series, ax=axes[0])
plot_pacf(differenced_series, ax=axes[1])
plt.show()

order = (1, 1, 1)
seasonal_order = (1, 1, 1, 2)
model = SARIMAX(time_series, order=order, seasonal_order=seasonal_order)
model_fit = model.fit(disp=False)
future_steps = 10
predictions = model_fit.predict(len(time_series), len(time_series) + future_steps - 1)
predictions = predictions.astype(int)
print(predictions)

# Create date indices for the future predictions
future_dates = pd.date_range(start=time_series.index[-1] + pd.DateOffset(days=1), periods=future_steps, freq='D')

# Create a pandas Series with the predicted values and date indices
forecasted_demand = pd.Series(predictions, index=future_dates)

# Initial inventory level
initial_inventory = 5500

# Lead time (number of days it takes to replenish inventory)
lead_time = 1

# Service level (probability of not stocking out)
service_level = 0.95

# Calculate the optimal order quantity using the Newsvendor formula
z = np.abs(np.percentile(forecasted_demand, 100 * (1 - service_level)))
order_quantity = np.ceil(forecasted_demand.mean() + z).astype(int)

# Calculate the reorder point
reorder_point = forecasted_demand.mean() * lead_time + z

# Calculate the optimal safety stock
safety_stock = reorder_point - forecasted_demand.mean() * lead_time

# Calculate the total cost (holding cost + stockout cost)
holding_cost = 0.1 # it's different for every business, 0.1 is an example
stockout_cost = 10 # # it's different for every business, 10 is an example
total_holding_cost = holding_cost * (initial_inventory + 0.5 * order_quantity)
total_stockout_cost = stockout_cost * np.maximum(0, forecasted_demand.mean() * lead_time - initial_inventory)

# Calculate the total cost
total_cost = total_holding_cost + total_stockout_cost

print("Optimal Order Quantity:", order_quantity)
print("Reorder Point:", reorder_point)
print("Safety Stock:", safety_stock)
print("Total Cost:", total_cost)

Understanding the code

We start with visualizing the ‘Demand over time’ and ‘Inventory over time’ from which a seasonal pattern can be observed. So we use SARIMA — Seasonal Autoregressive Moving Average to forecast the demand.

To use SARIMA we need p (auto-regressive order), d (degree of differencing), q (moving-average order), P (seasonal AR order), D (seasonal differencing) and Q (seasonal MA order). ACF — Autocorrelation function and PACF — Partial Autocorrelation function are plotted to find the parameter values.

Now to forecast we initialize few values. We set future steps i.e. days to forecast as 10, lead time i.e. number of days to replenish the inventory as 1 and other such retail store dependent values.

Finally to calculate inventory optimal result, we use NewsVendor formula. NewsVendor formula is derived from NewsVendor model which is a mathematical model used to determine optimal inventory level. You can learn more about NewsVendor formula from this article.

The final results evaluated are,

  1. Optimal order quantity — Refers to the quantity of a product that should be ordered from suppliers when the inventory level reaches a certain point.
  2. Reorder point — The inventory level at which a new order should be placed to replenish stock before it runs out.
  3. Safety stock — Additional inventory kept on hand to account for uncertainties in demand and supply. It acts as a buffer against unexpected variations in demand or lead time.
  4. Total cost — Represents the combined costs associated with inventory management.

The proposed SARIMA model digitized the retail store stock inventory management in an efficient way using the Newsvendor formula to calculate the optimal inventory needed to fulfill the customers while benefiting the retailers with maximum profit.

Hope this article may have helped you with what you were looking for. Any improvements or suggestions for the article are welcome. Cheers :)

Checkout my socials here and feel free to connect ^_^

--

--