Blackbox surrogate-based optimization framework
Project description
surrox
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bbb59152e71ff16448e9e62ff36dabbd4a69c3ac998e84f618d2d7a4d254f24e
|
|
| MD5 |
f07d5d09bc3e9c0761b76be5601d14d1
|
|
| BLAKE2b-256 |
62ba186670ff708bd07b6d97cd6e1a8880e70e2c70f96abc6e58eca869e38c1c
|
Provenance
The following attestation bundles were made for surrox-0.1.1.tar.gz:
Publisher:
release.yml on kint-pro/surrox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
surrox-0.1.1.tar.gz -
Subject digest:
bbb59152e71ff16448e9e62ff36dabbd4a69c3ac998e84f618d2d7a4d254f24e - Sigstore transparency entry: 1614825610
- Sigstore integration time:
-
Permalink:
kint-pro/surrox@4de008c67634f2c692349cbb55be055a7011ceda -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kint-pro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4de008c67634f2c692349cbb55be055a7011ceda -
Trigger Event:
workflow_dispatch
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03b808427ff03e6423ea762de74beef80577920145276c422a6ffda6bf080c3a
|
|
| MD5 |
abbd8af74cb564602faa19f003a1646c
|
|
| BLAKE2b-256 |
400014b886bde1cf640ea309df492c845b5c4124259bc4d75e8bbe8b3cb6778d
|
Provenance
The following attestation bundles were made for surrox-0.1.1-py3-none-any.whl:
Publisher:
release.yml on kint-pro/surrox
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
surrox-0.1.1-py3-none-any.whl -
Subject digest:
03b808427ff03e6423ea762de74beef80577920145276c422a6ffda6bf080c3a - Sigstore transparency entry: 1614825617
- Sigstore integration time:
-
Permalink:
kint-pro/surrox@4de008c67634f2c692349cbb55be055a7011ceda -
Branch / Tag:
refs/heads/main - Owner: https://github.com/kint-pro
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@4de008c67634f2c692349cbb55be055a7011ceda -
Trigger Event:
workflow_dispatch
-
Statement type: