Metadata-Version: 2.4
Name: eb-metrics
Version: 0.2.9
Summary: Core Electric Barometer error metrics, including asymmetric CWSL and standard forecast loss functions.
Author-email: "Kyle Corrie (Economistician)" <kcorrie@economistician.com>
License-Expression: BSD-3-Clause
Project-URL: Homepage, https://github.com/Economistician/eb-metrics
Project-URL: Repository, https://github.com/Economistician/eb-metrics
Project-URL: Issues, https://github.com/Economistician/eb-metrics/issues
Project-URL: Documentation, https://github.com/Economistician/eb-docs
Keywords: forecasting,metrics,evaluation,time-series,operations-research
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Provides-Extra: test
Requires-Dist: pytest>=8.0; extra == "test"
Requires-Dist: scikit-learn>=1.3; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-cov>=5.0; extra == "dev"
Requires-Dist: ruff>=0.0.1; extra == "dev"
Requires-Dist: pyright>=1.1; extra == "dev"
Requires-Dist: twine>=4.0; extra == "dev"
Provides-Extra: sklearn
Requires-Dist: scikit-learn>=1.3; extra == "sklearn"
Provides-Extra: tf
Requires-Dist: tensorflow>=2.13; extra == "tf"
Provides-Extra: all
Requires-Dist: scikit-learn>=1.3; extra == "all"
Requires-Dist: tensorflow>=2.13; extra == "all"
Requires-Dist: pytest>=8.0; extra == "all"
Requires-Dist: pytest-cov>=5.0; extra == "all"
Requires-Dist: ruff>=0.0.1; extra == "all"
Requires-Dist: pyright>=1.1; extra == "all"
Requires-Dist: twine>=4.0; extra == "all"
Dynamic: license-file

# Electric Barometer · Metrics (`eb-metrics`)

[![CI](https://github.com/Economistician/eb-metrics/actions/workflows/ci.yml/badge.svg)](https://github.com/Economistician/eb-metrics/actions/workflows/ci.yml)
![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD_3--Clause-blue.svg)
![Python Versions](https://img.shields.io/pypi/pyversions/eb-metrics)
![PyPI](https://img.shields.io/pypi/v/eb-metrics)

Asymmetric, readiness-oriented forecast evaluation metrics for operational decision systems.

---

## Overview

`eb-metrics` defines asymmetric, readiness-oriented forecast evaluation primitives (CWSL, NSL, UD, HR@τ, FRS, and related measures). It owns metric math only; evaluation orchestration, policies, and adapters live in sibling packages.

---

## Installation

`eb-metrics` is distributed as a standard Python package.

```bash
pip install eb-metrics
```

The package supports Python 3.11 and later.

---

## Core Concepts

- **Asymmetric error** — Overforecasting and underforecasting can have different operational consequences, so evaluation should reflect directional cost differences.
- **Interval reliability** — In readiness-oriented systems, it matters how often forecasts meet demand within each interval, not just average error over time.
- **Shortfall behavior** — Underbuilding events are operationally distinct; evaluation should capture both their frequency and their severity.
- **Tolerance-based adequacy** — Many systems can absorb small deviations; reliability can be expressed as the frequency of “accurate enough” intervals.
- **Readiness-oriented evaluation** — Forecast quality is assessed by execution feasibility and risk, not solely statistical deviation.

---

## Minimal Example

The following example computes Cost-Weighted Service Loss (CWSL) for a single demand series using asymmetric penalties for underbuild and overbuild:

```python
import numpy as np
from eb_metrics import cwsl

# Realized demand and corresponding forecast
y_true = np.array([20, 28, 32, 35, 40, 42])
y_pred = np.array([22, 25, 29, 36, 37, 45])

# Compute cost-weighted service loss
loss = cwsl(
    y_true=y_true,
    y_pred=y_pred,
    cu=2.0,
    co=1.0,
)

print(loss)
```

---

## License

BSD 3-Clause License.
© 2026 Kyle Corrie.
