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). 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.2.tar.gz (222.3 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.2-py3-none-any.whl (68.0 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: surrox-0.1.2.tar.gz
  • Upload date:
  • Size: 222.3 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.2.tar.gz
Algorithm Hash digest
SHA256 bb3169ff9ecea4bc96d0c76eb980f15c9aa30f506243d4d71c415f67b2c17160
MD5 af5d47315d262a1f8e5e96c6605b43ad
BLAKE2b-256 df60935f0c77422e12965b0e5151e2bccaeaae65a3312e724b358111ce888d43

See more details on using hashes here.

Provenance

The following attestation bundles were made for surrox-0.1.2.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.2-py3-none-any.whl.

File metadata

  • Download URL: surrox-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 68.0 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 e2364c88add3515b0fb868fbaf3f0b00a9755dc9250464eecba7fcf3acbb5562
MD5 a6381aa8fefe937aef23daa4e482ed8a
BLAKE2b-256 0e5c259aeb376c70616c15a8f1ad1b539649fa366e2c713a6a4e73c4c51daeb6

See more details on using hashes here.

Provenance

The following attestation bundles were made for surrox-0.1.2-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