skills/demand-forecasting/SKILL.md
When the user wants to forecast demand, build forecasting models, or improve forecast accuracy. Also use when the user mentions "demand planning," "sales forecasting," "time series," "forecast accuracy," "demand sensing," "statistical forecasting," or "predictive analytics." For capacity planning based on forecasts, see capacity-planning. For S&OP integration, see sales-operations-planning.
npx skillsauth add kishorkukreja/awesome-supply-chain demand-forecastingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an expert in demand forecasting and planning. Your goal is to help build accurate, reliable forecasting models that drive better inventory, production, and supply chain decisions.
Before building forecasts, understand:
Business Context
Data Availability
Demand Characteristics
Current State
1. Stable/Level Demand
2. Trend Demand
3. Seasonal Demand
4. Intermittent/Lumpy Demand
5. Promotional Demand
Moving Average
# Simple Moving Average
import pandas as pd
import numpy as np
def moving_average(data, window=3):
"""Calculate moving average forecast"""
return data.rolling(window=window).mean()
# Example
forecast = moving_average(sales_data, window=3)
Exponential Smoothing
from statsmodels.tsa.holtwinters import SimpleExpSmoothing
def exponential_smoothing(data, alpha=0.3):
"""Simple exponential smoothing"""
model = SimpleExpSmoothing(data)
fitted = model.fit(smoothing_level=alpha, optimized=False)
return fitted
Holt's Linear Trend
from statsmodels.tsa.holtwinters import Holt
def holts_method(data, alpha=0.8, beta=0.2):
"""Holt's linear trend method"""
model = Holt(data)
fitted = model.fit(smoothing_level=alpha, smoothing_trend=beta)
return fitted
Holt-Winters Seasonal
from statsmodels.tsa.holtwinters import ExponentialSmoothing
def holt_winters(data, seasonal_periods=12, seasonal='add'):
"""Holt-Winters exponential smoothing"""
model = ExponentialSmoothing(
data,
seasonal_periods=seasonal_periods,
trend='add',
seasonal=seasonal
)
fitted = model.fit()
return fitted
# Forecast future periods
forecast = fitted.forecast(steps=6)
ARIMA Models
from statsmodels.tsa.arima.model import ARIMA
def arima_forecast(data, order=(1,1,1)):
"""ARIMA forecasting model"""
model = ARIMA(data, order=order)
fitted = model.fit()
return fitted
# Auto ARIMA for parameter selection
from pmdarima import auto_arima
auto_model = auto_arima(data, seasonal=True, m=12)
Linear Regression with Features
from sklearn.linear_model import LinearRegression
import pandas as pd
def causal_forecast(X_features, y_demand):
"""Linear regression with causal factors"""
model = LinearRegression()
model.fit(X_features, y_demand)
return model
# Example features
features = pd.DataFrame({
'price': prices,
'promotion': promotions, # 0 or 1
'holiday': holidays, # 0 or 1
'competitor_price': comp_prices
})
Multiple Linear Regression
Random Forest
from sklearn.ensemble import RandomForestRegressor
def ml_forecast_rf(X_train, y_train, n_estimators=100):
"""Random Forest forecasting"""
model = RandomForestRegressor(
n_estimators=n_estimators,
max_depth=10,
random_state=42
)
model.fit(X_train, y_train)
return model
# Feature importance
importances = model.feature_importances_
Gradient Boosting (XGBoost, LightGBM)
import xgboost as xgb
def ml_forecast_xgb(X_train, y_train):
"""XGBoost forecasting"""
model = xgb.XGBRegressor(
objective='reg:squarederror',
n_estimators=100,
learning_rate=0.1,
max_depth=6
)
model.fit(X_train, y_train)
return model
Neural Networks (LSTM)
from tensorflow import keras
from keras.models import Sequential
from keras.layers import LSTM, Dense
def lstm_forecast(X_train, y_train, timesteps=10, features=1):
"""LSTM neural network forecast"""
model = Sequential([
LSTM(50, activation='relu', input_shape=(timesteps, features)),
Dense(1)
])
model.compile(optimizer='adam', loss='mse')
model.fit(X_train, y_train, epochs=50, batch_size=32)
return model
Prophet (Facebook)
from prophet import Prophet
def prophet_forecast(df):
"""Facebook Prophet forecasting"""
# df needs 'ds' (date) and 'y' (value) columns
model = Prophet(
yearly_seasonality=True,
weekly_seasonality=True,
daily_seasonality=False
)
model.fit(df)
# Make future dataframe
future = model.make_future_dataframe(periods=90)
forecast = model.predict(future)
return model, forecast
Croston's Method
import numpy as np
def crostons_method(demand, alpha=0.1):
"""Croston's method for intermittent demand"""
forecast = []
avg_demand = 0
avg_interval = 1
time_since_last = 0
for d in demand:
time_since_last += 1
if d > 0:
avg_demand = alpha * d + (1 - alpha) * avg_demand
avg_interval = alpha * time_since_last + (1 - alpha) * avg_interval
time_since_last = 0
forecast.append(avg_demand / avg_interval if avg_interval > 0 else 0)
return forecast
TSB (Teunter-Syntetos-Babai)
Bootstrapping
MAD (Mean Absolute Deviation)
def mad(actual, forecast):
"""Mean Absolute Deviation"""
return np.mean(np.abs(actual - forecast))
MAPE (Mean Absolute Percentage Error)
def mape(actual, forecast):
"""Mean Absolute Percentage Error"""
return np.mean(np.abs((actual - forecast) / actual)) * 100
RMSE (Root Mean Square Error)
def rmse(actual, forecast):
"""Root Mean Square Error"""
return np.sqrt(np.mean((actual - forecast) ** 2))
Bias (Forecast Bias)
def bias(actual, forecast):
"""Forecast bias (positive = over-forecast)"""
return np.mean(forecast - actual)
Tracking Signal
def tracking_signal(actual, forecast):
"""Cumulative bias / MAD"""
errors = forecast - actual
cumulative_error = np.cumsum(errors)
mad_value = np.mean(np.abs(errors))
return cumulative_error / mad_value if mad_value > 0 else 0
| Category | Target MAPE | Notes | |----------|-------------|-------| | A items (high volume) | 15-25% | Tightest control | | B items (medium) | 25-40% | Moderate | | C items (low volume) | 40-60% | Wider tolerance | | New products | 50-80% | High uncertainty | | Promotional | 30-50% | Event-dependent |
Classification:
XYZ Analysis (Variability):
Combined ABC-XYZ Matrix:
| | A (High Value) | B (Medium) | C (Low Value) | |-----|----------------|------------|---------------| | X | Tight control, advanced methods | Standard methods | Simple methods | | Y | Advanced methods + safety stock | Standard methods | Simple/aggregate | | Z | ML/causal + high safety stock | Croston's | Min/Max or don't stock |
Data Cleaning:
# Remove outliers using IQR method
Q1 = df['demand'].quantile(0.25)
Q3 = df['demand'].quantile(0.75)
IQR = Q3 - Q1
df_clean = df[~((df['demand'] < (Q1 - 1.5 * IQR)) |
(df['demand'] > (Q3 + 1.5 * IQR)))]
Feature Engineering:
# Create time-based features
df['month'] = df['date'].dt.month
df['day_of_week'] = df['date'].dt.dayofweek
df['is_weekend'] = df['day_of_week'].isin([5, 6]).astype(int)
df['is_holiday'] = df['date'].isin(holidays).astype(int)
# Lag features
df['lag_1'] = df['demand'].shift(1)
df['lag_7'] = df['demand'].shift(7)
df['rolling_mean_7'] = df['demand'].rolling(7).mean()
Decision Tree:
Start
├─ Intermittent demand (many zeros)?
│ └─ Yes → Croston's, TSB, or aggregate
│ └─ No → Continue
├─ Strong seasonality?
│ └─ Yes → Holt-Winters, SARIMA, or Prophet
│ └─ No → Continue
├─ Trend present?
│ └─ Yes → Holt's trend, ARIMA
│ └─ No → Continue
├─ External factors available?
│ └─ Yes → Regression, ML models
│ └─ No → Simple smoothing
└─ Default: Exponential smoothing or Moving Average
Statistical Forecast:
# Generate forecast with confidence intervals
forecast = model.forecast(steps=12)
conf_int = model.forecast_interval(steps=12, alpha=0.05) # 95% CI
Add Business Intelligence:
Forecast Override Process:
Weighted Combination:
# Combine statistical and judgmental
final_forecast = (
0.7 * statistical_forecast +
0.3 * sales_team_forecast
)
Monitor Metrics:
Top-Down:
Bottom-Up:
Middle-Out:
Optimal Reconciliation:
from hierarchicalforecast.utils import aggregate
from hierarchicalforecast.methods import BottomUp, TopDown, MinTrace
# Define hierarchy
hierarchy = {
'Total': ['Region_A', 'Region_B'],
'Region_A': ['SKU_1', 'SKU_2'],
'Region_B': ['SKU_3', 'SKU_4']
}
# Reconcile forecasts
reconciled = MinTrace().fit_predict(forecasts, hierarchy)
Concept:
def forecast_value_added(actual, baseline_fcst, adjusted_fcst):
"""Calculate if adjustments added value"""
baseline_error = np.abs(actual - baseline_fcst)
adjusted_error = np.abs(actual - adjusted_fcst)
fva = baseline_error - adjusted_error
# Positive FVA = adjustment improved forecast
return fva
Real-Time Signals:
Short-Term Adjustments:
Statistical Forecasting:
statsmodels: ARIMA, exponential smoothing, seasonal decompositionpmdarima: Auto ARIMAprophet: Facebook Prophetsktime: Time series MLMachine Learning:
scikit-learn: Regression, tree-based modelsxgboost, lightgbm: Gradient boostingtensorflow, pytorch: Deep learning (LSTM, transformers)Utilities:
pandas: Data manipulationnumpy: Numerical computationsmatplotlib, seaborn, plotly: VisualizationSolutions:
Solutions:
Solutions:
Solutions:
Solutions:
Solutions:
Executive Summary:
Demand Forecast by Segment:
| Product/SKU | Location | Period | Statistical Fcst | Adjusted Fcst | Actual (Prior) | MAPE | Bias | |-------------|----------|--------|------------------|---------------|----------------|------|------| | Product A | DC1 | Jan 2025 | 10,000 | 10,500 | 9,800 | 7.1% | +7.1% | | ... | ... | ... | ... | ... | ... | ... | ... |
Forecast Assumptions:
Accuracy Metrics:
Action Items:
If you need more context:
documentation
When the user wants to optimize yard operations, manage trailer parking, or improve dock door utilization. Also use when the user mentions "yard management," "trailer tracking," "yard jockey," "drop trailer program," "trailer pool," "dock scheduling," or "gate management." For cross-dock operations, see cross-docking. For warehouse design, see warehouse-design.
tools
When the user wants to optimize workforce scheduling, create shift plans, or balance labor demand. Also use when the user mentions "staff scheduling," "labor planning," "shift optimization," "crew scheduling," "roster optimization," or "employee scheduling." For task assignment, see task-assignment-problem. For wave planning labor, see wave-planning-optimization.
testing
When the user wants to optimize pick wave planning, schedule warehouse operations, or improve order fulfillment efficiency. Also use when the user mentions "wave management," "batch picking," "pick wave scheduling," "order release optimization," "wave design," or "pick wave strategy." For order batching, see order-batching-optimization. For workforce scheduling, see workforce-scheduling.
testing
When the user wants to optimize warehouse slot assignments, improve pick efficiency, or design warehouse layouts. Also use when the user mentions "slotting optimization," "slot assignment," "ABC slotting," "pick path optimization," "storage location assignment," "warehouse layout optimization," or "forward pick locations." For picker routing, see picker-routing-optimization. For warehouse design, see warehouse-design.