Skip to main content

brillQ OPEX Benchmark

Bayesian cost-frontier benchmarking of operational expenditure (OPEX). A commercial Python library by brillQ, Warsaw, Poland, published on PyPI as brillq-opex-benchmark. It installs the Python package brillq_opex and the command-line tool brillq-opex.

Licence. brillQ OPEX Benchmark is commercial software of brillQ sp. z o.o. Without a licence key it runs in evaluation mode: all features, at most 30 units per analysis of your own data; the built-in demonstration panels run in full. Use beyond evaluation requires a licence key; contact hello@brillq.today. The licence agreement (LICENSE.txt) is included in the package.

The library answers six questions about a set of comparable units (network areas, plants, branches, subsidiaries, hospitals, stores, departments):

  1. Do the data show inefficiency at all? Before anything that counts units or money is reported, three safeguards run: a residual screening rule without a quota, a curvature check and an evidence gate. When the cross-section does not establish inefficiency, the report says so and withholds efficiencies, savings and efficiency-gap recommendations.
  2. How efficient is each unit, and how sure are we? A Bayesian stochastic cost frontier gives every unit a posterior distribution of cost efficiency, credible intervals and a rank distribution instead of a single point.
  3. Where does the money go? Observed cost is decomposed into frontier cost, a stochastic component and excess cost; savings at a target efficiency come with credible intervals, next to the assumptions they rest on and their sensitivity to those assumptions.
  4. What is associated with excess cost? A second-stage model with Shapley attributions ranks operational metrics (failure rates, asset age, length of stay, staff turnover) and says when they carry no reliable signal. Its findings are reported as associations, not causes.
  5. Which records should be checked first? Units whose cost is far from what their frontier variables imply are set aside, scored against the frontier of the others and listed as data-quality items, with a checklist and a scenario of the saving if the records prove real.
  6. Which savings can be defended, and at what cost to quality and capital? The savings become a portfolio: an expected saving weighted by the probability that each unit is below the target, the amount reached with 95 % probability, and baskets (secure, large but uncertain, conditional on quality, other, to verify). Savings of units whose quality (for example SAIDI and SAIFI) is among the worst are not counted. With a capital cost in the data the same frontier is fitted to total cost (TOTEX), which shows capitalisation and deferred renewals; every saving comes with the investment it pays back, and cost components separate the controllable part of the excess.

The result is a traceable, quantified list of recommendations, a client report (one HTML file with charts, findings and an action plan, printable to PDF), an analyst workbook (Excel), JSON and Markdown, in English or Polish. Forecasting of OPEX series (exponential smoothing with back-test selection) is included.

The methodology and its validation are described in A. B. Brill, "Explainable Bayesian Cost-Frontier Analytics for Operational Expenditure Benchmarking: Method, Monte Carlo Validation and Empirical Applications", brillQ & LastHuman R&D Lab technical paper (preprint), 2026 (ResearchGate). Version 2.0 implements the safeguards and the sampler that the paper recommends.

A Polish README (README.pl.md), a Polish user guide (docs/guide.pl.md) and the full documentation (docs/) are included in the source distribution.


Installation

# core (numpy, scipy, pandas, scikit-learn, pydantic, cryptography, tabulate)
pip install brillq-opex-benchmark

# recommended: XGBoost + SHAP explanations and Excel export
pip install "brillq-opex-benchmark[ml,excel]"

# everything (adds the PyMC/ArviZ NUTS backend and statsmodels forecasting)
pip install "brillq-opex-benchmark[all]"

Python 3.10 or newer. No compiled extensions; the wheel is platform-independent. Earlier releases were distributed as brillq-opex-analytics (2.0) and brillq-opex (1.x). All of them install the same package brillq_opex, so uninstall the old one first (pip uninstall brillq-opex-analytics brillq-opex), then install brillq-opex-benchmark and replace the name in requirement files. Code, the command and licence keys stay as they are; for the changes of 2.0 see docs/migration-2.0.md in the source distribution.

Try it first

brillq-opex demo                                     # 100 network areas of a utility, full report
brillq-opex demo --sector hospitals --language pl    # also: branches, plants, subsidiaries
brillq-opex demo --report demo.html                  # the client report: open it in a browser

The demonstration panels are synthetic, with known inefficiency, two gross cost errors and two true drivers among the operational metrics. The output ends with this known truth, so the estimates can be checked against it. The panels run in full in evaluation mode; in Python they are generate_demo_panel("hospitals").panel.

Licence activation

Without a key the library runs in evaluation mode (all features, at most 30 units per analysis of your own data, evaluation notice; the built-in demonstration panels run in full). Keys are verified offline; keys issued for 1.x remain valid.

brillq-opex license "BQOPEX-..." --save     # stores the key in ~/.brillq/opex.lic
# or
export BRILLQ_OPEX_LICENSE_KEY="BQOPEX-..."
import brillq_opex
brillq_opex.activate("BQOPEX-...")          # per process
print(brillq_opex.license_status().describe())

Commercial licences: hello@brillq.today. The terms are in LICENSE.txt, included in the package.


Quick start

import pandas as pd
from brillq_opex import CostPanel, OpexAnalyzer

df = pd.read_csv("units.csv")                  # one row per unit
panel = CostPanel.from_dataframe(
    df,
    cost_col="annual_opex",
    driver_cols=["customers", "network_km", "stations"],      # outputs and scale variables
    condition_cols=["service_area_km2"],                      # conditions the units cannot choose
    indicator_cols=["urban"],                                 # 0/1 conditions
    price_cols=[],                                            # input-price indices, if any
    metric_cols=["failure_rate", "asset_age", "utilisation", "overtime_share"],
    id_col="unit_id", group_col="region",
)

report = OpexAnalyzer(target_efficiency=0.90, currency="PLN", language="en",
                      sector="dso", seed=42).run(panel)
print(report.summary())                         # status, evidence gate, results, reliability notes

report.status                  # "established" | "not_established" | "gate_off"
report.safeguards.table()      # screening, curvature check, evidence gate
report.screening               # residual, robust z-score and decision for every unit
if not report.withheld:
    report.efficiency          # posterior mean, equal-tailed and highest-density intervals, ranks
    report.decomposition.table # efficient vs excess cost with intervals
    report.savings             # savings at the target efficiency
    report.sensitivity         # the same figures under other priors and the other law
report.recommendations         # data-quality items first, then quantified items per unit
report.to_html("opex_report.html")    # client report (see Reports below)
report.to_excel("opex_report.xlsx")   # analyst workbook

When the evidence gate is closed, report.withheld is true, report.ols holds the OLS cost function and report.portfolio_summary the statement that the cross-section does not establish inefficiency.

Command line:

brillq-opex demo --sector hospitals --excel demo.xlsx     # Excel export needs the [excel] extra
brillq-opex sectors dso --language pl
brillq-opex analyze units.csv --cost-col annual_opex \
    --drivers customers network_km stations --conditions service_area_km2 --indicators urban \
    --metrics failure_rate asset_age utilisation --id-col unit_id --language pl --excel report.xlsx
brillq-opex analyze units.csv --cost-col opex --drivers customers network_km \
    --conditions service_area_km2 forest_share --capex-col capex --quality SAIDI SAIFI \
    --quality-limit SAIDI 150 --components own_labour contracted_services shared_services \
    --noncontrollable shared_services --group-col group --group-note "quartiles of customer density" \
    --report report.html

Reports

report.to_html("report.html") writes the client report: one self-contained HTML file for management (no external resources; it works offline and can be sent by e-mail). It opens with the key figures, the findings and where to start, then shows the whole analysis in charts: the evidence of inefficiency, the efficiency of every unit with its interval, where the money goes, the savings by unit, robustness, what goes with higher cost, peer groups, profiles of the units with the largest potential and an action plan by unit, followed by data quality, the method and a sortable table of all units. With the decision layer it adds the savings portfolio (baskets, the defensible amount, the quality condition and the scenario of the records to verify), investment and total cost (TOTEX ranks, flags and the break-even investment), cost components, benchmark profiles of the peer groups and the limits of the method. Every chart has a table view and tooltips; the browser's Print gives an A4 PDF.

report.to_html("opex_report.html", client="Client name", logo="client_logo.png")
report.to_excel("opex_report.xlsx")       # analyst workbook
report.to_markdown("opex_report.md")      # the client report as text

The analyst workbook follows the report language: a summary with the key figures, findings and native charts, then the portfolio (baskets, scenario and a decision table of every unit), every unit, the action plan, TOTEX, cost components, drivers and their per-unit contributions, peer groups and benchmark profiles, sensitivity, data quality, the model and the input data. Numbers stay numbers, headers are frozen and filterable. to_excel(path, layout="data") writes the raw tables, one per sheet, as in 2.0.

brillq-opex demo --language pl --report demo.html
brillq-opex analyze units.csv ... --report report.html --client "Client name" --logo logo.png

Data requirements

Column type Role Meaning Requirements
cost operating cost of the unit for one period > 0, same currency, period and cost scope for all units
outputs and scale variables scale what the unit has to serve: customers, cases, transactions, network length > 0 (they enter in logarithms)
conditions condition what the unit cannot choose: service area, case mix, product mix, location type > 0; 0/1 conditions via indicator_cols
input-price indices price regional wage index, energy prices, where units buy at different prices > 0
metrics (optional) controllable indicators used to explain inefficiency finite
group (optional) peer group (region, segment) for benchmark items any label; state how the groups were formed with notes={"groups": ...}
capital cost (optional) capex_col annual capital cost (depreciation and return), for the TOTEX view >= 0 for every unit
quality (optional) quality_cols quality indicators such as SAIDI and SAIFI; lower is better unless quality_better says "higher" finite; > 0 to enter the frontier
cost components (optional) component_cols parts of the cost (own labour, contracted services, ...); noncontrollable_cols marks those outside the unit's control >= 0, adding up to the cost

Only scale variables enter the cost elasticity of scale, the size index of the curvature check and the cost intensities of the anomaly screen. A variable that the management of a unit cannot influence and that legitimately changes cost belongs in the frontier; left out, or moved to the metrics, it is read as inefficiency. brillq-opex sectors prints typical specifications for five kinds of organisations.

Rule of thumb: at least 30 units and 8 to 10 units per frontier variable. With fewer than about 60 units the priors carry considerable weight and the evidence gate has little power; the report says so.


What the analysis does

Log cost is modelled as a stochastic cost frontier

ln C_i = b0 + b' z_i + v_i + u_i,      v_i ~ N(0, s_v^2),   u_i >= 0  (half-normal or exponential)

with z_i the standardised logarithms of the frontier variables. Cost efficiency is exp(-u_i). The pipeline runs:

  1. Residual screening (no quota): units whose OLS residual has a robust z-score above 3.5 in absolute value are set aside, on either side.
  2. Curvature check: a squared size index is added to the frontier and kept if the 95 % interval of its coefficient excludes zero.
  3. Evidence gate: the skewness test of the OLS residuals under the final specification must reject the absence of inefficiency at the 5 % level.
  4. Bayesian frontier on the units that remain, by adaptive random-walk Metropolis on the posterior with the inefficiencies integrated out; units set aside are scored against it.
  5. Decomposition, efficiency, savings, with equal-tailed intervals by default.
  6. Second stage (drivers of inefficiency) behind its reliability gate.
  7. Recommendations: data-quality items first; efficiency-gap, driver and peer items only when the evidence gate is open.
  8. Sensitivity and reliability notes: refits under a prior median efficiency of 0.70 and 0.95 and under the other inefficiency law; notes on weak signals, small panels, a narrowly open gate, size-dependent residual spread and convergence.
  9. Decision layer: the posterior draws of the savings become a portfolio (expected and 5 % quantile, baskets, scenario of the records set aside, break-even investment over capex_horizon years at discount_rate), with the quality condition (quality_tail, quality_limits or quality_in_frontier), cost components and, when every unit has a capital cost, the same frontier on TOTEX with flags for capitalisation, deferred renewal and an OPEX gap offset by low capital cost. Recommendation priorities follow the baskets.

Priors are proper and weakly informative; the hyper-parameter a user normally sets is the prior median efficiency r* (default 0.85). Baselines (mle_fit, cols_fit) implement maximum likelihood with JLMS / Battese-Coelli efficiencies and Horrace-Schmidt intervals, and corrected OLS. backend="gibbs" runs the data-augmentation sampler of 1.x and backend="nuts" the same model in PyMC.

Details, assumptions and references: docs/methodology.md; API: docs/api.md; Polish user guide: docs/guide.pl.md (all in the source distribution).


Package layout

brillq_opex/
  data.py            CostPanel / UnitRecord (validated inputs, roles, size index, design matrix)
  synthetic.py       generators with known ground truth (panels of the paper, demonstration panels)
  safeguards.py      screening, curvature check, evidence gate, OLS cost function, evidence statistics
  frontier/
    model.py         BayesianCostFrontier (backends marginal | gibbs | nuts)
    marginal.py      adaptive random-walk Metropolis on the marginal posterior (default)
    gibbs.py         data-augmentation Gibbs sampler with partially collapsed refresh
    pymc_backend.py  optional NUTS backend
    priors.py        PriorConfig (half-Cauchy priors elicited by medians)
    likelihood.py    composed-error density, exact draws of u
    mle.py           ML (JLMS, Battese-Coelli, Horrace-Schmidt), COLS
    diagnostics.py   split R-hat, ESS (also vectorised), Geweke, MCSE, HDI
    results.py       FrontierResult (summaries, intervals, decomposition, scoring new units)
  decomposition.py   CostDecomposition (efficient / excess cost, savings at target)
  sensitivity.py     prior_sensitivity (refits under alternative assumptions)
  efficiency_ml.py   EfficiencyDriverModel (ridge or boosting + SHAP, reliability gate)
  anomaly.py         AnomalyDetector (residual, robust-z, Isolation Forest, ensemble; no quota)
  recommend.py       RecommendationEngine (EN/PL, whole-word action templates)
  sectors.py         sector templates (DSO, branches, plants, subsidiaries, hospitals)
  forecasting.py     OpexForecaster (Holt-Winters family, back-test, bootstrap intervals)
  pipeline.py        OpexAnalyzer / AnalysisConfig / AnalysisReport
  report.py          Excel / JSON / Markdown export
  licensing.py       offline Ed25519 licence keys, evaluation mode
  cli.py             brillq-opex command

Support

E-mail: hello@brillq.today. Web: https://brillq.today © 2026 brillQ sp. z o.o. All rights reserved. This software is licensed, not sold; see LICENSE.txt.

Metadata

Release files for brillq-opex-benchmark 2.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for brillq-opex-benchmark 2.1.0
File Size Uploaded Provenance Actions
brillq_opex_benchmark-2.1.0.tar.gz 295.7 kB Without provenance Details for brillq_opex_benchmark-2.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for brillq-opex-benchmark 2.1.0
File Interpreter ABI Platform Actions
brillq_opex_benchmark-2.1.0-py3-none-any.whl Python 3 none any Details for brillq_opex_benchmark-2.1.0-py3-none-any.whl

Total release size: 527.3 kB

Release files / brillq_opex_benchmark-2.1.0.tar.gz

Download URL brillq_opex_benchmark-2.1.0.tar.gz
Size 295.7 kB
Tags Source
SHA-256 checksum
How to use checksums
68f31c5979e3951a5f0a55a1c89b9b99cd93b9405d07dffabed36aac5f488a73
BLAKE2b-256 checksum
How to use checksums
af30a53f17263b68970cdf9e5baccaf7965701243a171a90173b1fefed269fd5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.7

Release files / brillq_opex_benchmark-2.1.0-py3-none-any.whl

Download URL brillq_opex_benchmark-2.1.0-py3-none-any.whl
Size 231.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
9b6021f8b077d326bf99da219b9f1b247c4881d6d9906f86380fd45259b33ce2
BLAKE2b-256 checksum
How to use checksums
97b1d985d603adc3c9af2c6c1027f2acd6a3a7194dd43dc3c4305a8436e644d1
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.7

Security for brillq-opex-benchmark 2.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page