Skip to main content

Blackbox surrogate-based optimization framework

Project description

surrox

License: Apache 2.0 Python 3.13

Your simulation takes 4 hours per run. You can't afford grid search. surrox trains surrogates on your existing data, optimizes on the cheap models instead, and tells you exactly why it picked each solution.

Data → Ensemble Surrogates → Multi-Objective Optimization → Explained Results

Quick Start

pip install surrox[all]
import numpy as np
import pandas as pd
from surrox import run, ProblemDefinition, Variable, Objective
from surrox import ContinuousBounds, DType, Direction, Role

rng = np.random.default_rng(42)
temperature = rng.uniform(150, 300, 500)
pressure = rng.uniform(1, 10, 500)
df = pd.DataFrame({
    "temperature": temperature,
    "pressure": pressure,
    "yield": 0.2 + 0.002 * temperature + 0.03 * pressure + rng.normal(0, 0.05, 500),
})

problem = ProblemDefinition(
    variables=(
        Variable(name="temperature", dtype=DType.CONTINUOUS, role=Role.DECISION,
                 bounds=ContinuousBounds(lower=150.0, upper=300.0)),
        Variable(name="pressure", dtype=DType.CONTINUOUS, role=Role.DECISION,
                 bounds=ContinuousBounds(lower=1.0, upper=10.0)),
    ),
    objectives=(
        Objective(name="maximize_yield", direction=Direction.MAXIMIZE, column="yield"),
    ),
)

result, analyzer = run(problem=problem, dataframe=df)

best = result.optimization.feasible_points[0]
print(best.variables)    # {"temperature": 284.0, "pressure": 9.06}
print(best.objectives)   # {"maximize_yield": 1.066}

importance = analyzer.feature_importance("yield")
print(importance.importances)  # {"temperature": 0.083, "pressure": 0.070}

What it does

You define the problem declaratively. surrox handles the rest.

Surrogates — Trains an ensemble per target column (XGBoost, LightGBM, Gaussian Process, TabICL). Optuna picks the hyperparameters. Conformal Prediction gives you calibrated uncertainty intervals, not just point estimates.

Optimization — Runs pymoo under the hood. Auto-selects the right algorithm based on your problem structure: DE for single-objective, NSGA-II for two objectives, NSGA-III for three or more. Supports linear and data-driven constraints.

Analysis — Every result comes with a summary: surrogate quality, constraint status, baseline comparison, extrapolation warnings. For deeper inspection, the Analyzer provides SHAP explanations, PDP/ICE curves, feature importance, what-if predictions, and trade-off analysis. All computed lazily and cached.

Scenarios — Fix context variables to specific values and compare outcomes across scenarios. Train surrogates once, optimize each scenario independently.

Suggest mode

Don't need the full pipeline? suggest gives you the top N candidates with uncertainty bounds.

from surrox import suggest

result = suggest(problem=problem, dataframe=df, n_suggestions=5)

for s in result.suggestions:
    print(s.variables)                            # {"temperature": 284.0, "pressure": 9.06}
    print(s.objectives["maximize_yield"].mean)    # 1.066
    print(s.objectives["maximize_yield"].lower)   # 0.978 (90% CI lower bound)
    print(s.is_extrapolating)                     # False

Problem definition

Everything is a Pydantic model. Immutable, validated at construction, type-safe.

from surrox import (
    ProblemDefinition, Variable, Objective, DataConstraint, Scenario,
    ContinuousBounds, IntegerBounds, CategoricalBounds,
    DType, Role, Direction, ConstraintOperator,
)

problem = ProblemDefinition(
    variables=(
        Variable(name="speed", dtype=DType.CONTINUOUS, role=Role.DECISION,
                 bounds=ContinuousBounds(lower=10.0, upper=100.0)),
        Variable(name="material", dtype=DType.CATEGORICAL, role=Role.DECISION,
                 bounds=CategoricalBounds(categories=("steel", "aluminum", "titanium"))),
        Variable(name="batch_size", dtype=DType.INTEGER, role=Role.CONTEXT,
                 bounds=IntegerBounds(lower=50, upper=500)),
    ),
    objectives=(
        Objective(name="max_strength", direction=Direction.MAXIMIZE, column="strength"),
        Objective(name="min_cost", direction=Direction.MINIMIZE, column="cost"),
    ),
    data_constraints=(
        DataConstraint(name="max_defect_rate", column="defect_rate",
                       operator=ConstraintOperator.LE, bound=0.05),
    ),
)

Architecture

Layer What it does
Problem Immutable problem definition: variables, objectives, constraints, scenarios
SurrogateManager Ensemble training, Optuna HPO, Conformal Prediction
Optimizer pymoo multi-objective optimization with constraint handling
Analysis SHAP, PDP/ICE, What-If, Trade-Off, Scenario Comparison

Development

uv sync
uv run pytest tests/ -v
uv run ruff check src/

See CONTRIBUTING.md for details.

License

MIT

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

surrox-0.1.1.tar.gz (230.9 kB view details)

Uploaded Source

Built Distribution

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

surrox-0.1.1-py3-none-any.whl (67.3 kB view details)

Uploaded Python 3

File details

Details for the file surrox-0.1.1.tar.gz.

File metadata

  • Download URL: surrox-0.1.1.tar.gz
  • Upload date:
  • Size: 230.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for surrox-0.1.1.tar.gz
Algorithm Hash digest
SHA256 bbb59152e71ff16448e9e62ff36dabbd4a69c3ac998e84f618d2d7a4d254f24e
MD5 f07d5d09bc3e9c0761b76be5601d14d1
BLAKE2b-256 62ba186670ff708bd07b6d97cd6e1a8880e70e2c70f96abc6e58eca869e38c1c

See more details on using hashes here.

Provenance

The following attestation bundles were made for surrox-0.1.1.tar.gz:

Publisher: release.yml on kint-pro/surrox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file surrox-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: surrox-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 67.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for surrox-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 03b808427ff03e6423ea762de74beef80577920145276c422a6ffda6bf080c3a
MD5 abbd8af74cb564602faa19f003a1646c
BLAKE2b-256 400014b886bde1cf640ea309df492c845b5c4124259bc4d75e8bbe8b3cb6778d

See more details on using hashes here.

Provenance

The following attestation bundles were made for surrox-0.1.1-py3-none-any.whl:

Publisher: release.yml on kint-pro/surrox

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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