Skip to main content

Cost-Weighted Service Loss (CWSL): an asymmetric forecast error framework for operational forecasting.

Project description

CWSL

license status

Cost-Weighted Service Loss (CWSL) is a forecast evaluation framework designed for environments where under-forecasting and over-forecasting do not have the same operational cost.

Traditional metrics like MAE, RMSE, and MAPE treat being 5 units short the same as being 5 units long.
CWSL makes this asymmetry explicit and quantifies its impact at the operational interval level.


What is CWSL?

CWSL is a demand-normalized, directionally-aware forecast error metric that applies higher penalties for shortfalls and lower penalties for overbuilds, reflecting their true operational costs.

It is designed for high-frequency operational decision-making where the timing and direction of forecast error matter as much as magnitude.

CWSL incorporates:

  • Asymmetric penalties (cu for shortfall, co for overbuild)
  • Interval-level evaluation (5–30 minute windows)
  • Demand normalization for cross-store and cross-item comparability
  • Additivity, enabling aggregation across items, categories, or stores

Quick Start

Example 1 — Basic Python Usage

from cwsl import cwsl

y_true = [10, 12, 8]
y_pred = [9, 15, 7]

cu = 2.0  # shortfall cost
co = 1.0  # overbuild cost

score = cwsl(y_true, y_pred, cu=cu, co=co)
print(score)

Example 2 — DataFrame Workflow

import pandas as pd
from cwsl import compute_cwsl_df

df = pd.DataFrame({
    "item": ["burger", "burger", "fries"],
    "actual": [10, 12, 8],
    "forecast": [9, 15, 7],
})

results = compute_cwsl_df(
    df,
    actual_col="actual",
    forecast_col="forecast",
    cu=2.0,
    co=1.0,
    groupby_cols=["item"]   # optional
)

print(results)

Example 3 - Grouped Evaluation

from cwsl import evaluate_groups_df

# df has columns: store_id, item_id, actual_qty, forecast_qty
group_summary = evaluate_groups_df(
    df,
    group_cols=["store_id", "item_id"],
    actual_col="actual_qty",
    forecast_col="forecast_qty",
    cu=2.0,
    co=1.0,
    tau=2.0,
)

print(group_summary.head())

Model Comparison Example

You can compare multiple forecast models on the same actuals using compare_forecasts.

import numpy as np
from cwsl import compare_forecasts

y_true = np.array([10, 12, 8])

forecasts = {
    "under_model": np.array([9, 11, 7]),
    "over_model":  np.array([12, 14, 10]),
    "naive_model": np.array([10, 12, 8]),
}

cu = 2.0  # shortfall cost
co = 1.0  # overbuild cost

df = compare_forecasts(
    y_true=y_true,
    forecasts=forecasts,
    cu=cu,
    co=co,
    tau=2.0,
)

print(df)

Included Metrics

This library implements CWSL and its supporting diagnostics:

Core Metric

  • CWSL – Cost-Weighted Service Loss

Diagnostics

  • NSL – No-Shortfall Level
  • HR@τ – Hit Rate within Tolerance
  • UD – Underbuild Depth
  • wMAPE – Weighted Mean Absolute Percentage Error
  • FRS – Forecast Readiness Score (NSL - CWSL)

These metrics together provide a multidimensional view of operational readiness.


Why CWSL Matters

In real-world operations:

  • Shortfalls cause lost transactions, slower service, queue buildup, recovery delays, and negative customer experience.
  • Overbuilds typically cause minor waste or brief excess capacity.

Despite this, most organizations rely on symmetric error metrics that treat ± error as interchangeable.

CWSL exposes readiness-related failures that symmetric metrics consistently hide:

  • Shortfall clustering at peak periods
  • Asymmetric operational consequences
  • Deep misses that matter more than shallow overbuilds
  • Interval-level vulnerability that MAE/MAPE smooth over

If operational reliability matters, CWSL is the metric that aligns with reality.


Who Is CWSL For?

CWSL is applicable to any domain with short-horizon operational decisions, including:

  • Quick-service restaurants (QSR) & foodservice
  • Retail replenishment & on-shelf availability
  • Workforce & capacity planning
  • Manufacturing & production scheduling
  • Logistics & last-mile delivery
  • Energy & short-term load forecasting
  • Inventory & supply chain systems

If being “short” is worse than being “long,” CWSL applies.


Project Status

This project is under active development.

Planned for v0.1.0

  • Implement core metrics (CWSL, NSL, HR@τ, UD, wMAPE, FRS)
  • Add cwsl_from_df for item–interval DataFrame workflows
  • Publish on PyPI (pip install cwsl)
  • Add example notebooks (QSR, retail, workforce planning)
  • Add visualization tools for asymmetric penalties
  • Add CWSL-based model comparison utilities

Planned for v0.2.0

  • Add more DataFrame utilities (multi-item, multi-store)
  • Add scikit-learn scorer wrappers
  • Add plot_cwsl_breakdown() visualization tools
  • Add asymmetric cost sensitivity analysis utilities
  • Add model comparison suite (compare_models_cwsl)
  • Add documentation site (MkDocs + GitHub Pages)

Connect

If you'd like to discuss forecasting, operations, analytics, or the CWSL framework:

Created by Kyle Corrie (Economistician) Founder of the CWSL Metric and the Forecast Readiness Framework

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cwsl-0.1.2.tar.gz (15.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cwsl-0.1.2-py3-none-any.whl (12.2 kB view details)

Uploaded Python 3

File details

Details for the file cwsl-0.1.2.tar.gz.

File metadata

  • Download URL: cwsl-0.1.2.tar.gz
  • Upload date:
  • Size: 15.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for cwsl-0.1.2.tar.gz
Algorithm Hash digest
SHA256 c871995c451f71c89627d4b25720e5db7e67451bf19e4d5a7f03df10c021ad23
MD5 bde39e5bef5eee1c0f7f696f8a892525
BLAKE2b-256 44456193b9a4a9cf5ed26b7700229710af5015e1c72f711be13df84af4eef721

See more details on using hashes here.

File details

Details for the file cwsl-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: cwsl-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 12.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for cwsl-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4ec759286b48a45741ac8c328c32fdd100bf4df12aa18ffca25b370b8187b3bf
MD5 4738edb49a59e76a0b47ffac0ec23aa5
BLAKE2b-256 fe912b4d23faffeee7a4d2c58e23f63117d521b10e8d876a886a91f620934c71

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page