
Parameter Optimization
- 16 installs
- 869 repo stars
- Updated June 8, 2026
- beita6969/scienceclaw
Parameter Optimization is a skill that explores and optimizes simulation parameters via design of experiments, sensitivity analysis, and optimizer selection.
About
Provides a workflow to explore and optimize simulation parameters through design of experiments, sensitivity analysis, and optimizer selection. An engineer uses it to calibrate materials simulations by generating LHS or Sobol samples, ranking parameter influence, and choosing between Bayesian optimization, CMA-ES, or random search. It ships pure-Python scripts that emit JSON and require no external dependencies.
- Designs experiments and ranks parameter influence for simulation calibration
- Decision guidance for DOE methods (LHS, Sobol, factorial) and optimizers
- Pure-Python scripts for DOE generation, sensitivity, optimizer choice, and surrogates
Parameter Optimization by the numbers
- 16 all-time installs (skills.sh)
- Ranked #1,318 of 2,065 Data Science & ML skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
parameter-optimization capabilities & compatibility
Free; pure-Python standard-library scripts, no dependencies
- Capabilities
- design of experiments · sensitivity analysis · optimizer selection
- Use cases
- data analysis
- Runs
- Runs locally
- Pricing
- Free
What parameter-optimization says it does
Explore and optimize simulation parameters via design of experiments (DOE), sensitivity analysis, and optimizer selection.
No external dependencies (uses Python standard library only)
npx skills add https://github.com/beita6969/scienceclaw --skill parameter-optimizationAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 16 |
|---|---|
| repo stars | ★ 869 |
| Last updated | June 8, 2026 |
| Repository | beita6969/scienceclaw ↗ |
What it does
Design experiments, rank parameter sensitivity, and select optimizers for simulation calibration.
Who is it for?
Calibrating simulations with DOE sampling, sensitivity ranking, and optimizer selection
Skip if: Real-time optimization loops or running simulations, which the docs say the user must do externally
When should I use this skill?
You need calibration, parameter sweeps, LHS/Sobol sampling, sensitivity analysis, or optimizer setup
What you get
DOE sample points, a parameter sensitivity ranking, and an optimizer recommendation as JSON.
- DOE sample points (JSON)
- Parameter sensitivity ranking
- Optimizer recommendation
By the numbers
- 4 bundled Python scripts
- 3 DOE methods (lhs, sobol, factorial)
Files
Parameter Optimization
Goal
Provide a workflow to design experiments, rank parameter influence, and select optimization strategies for materials simulation calibration.
Requirements
- Python 3.8+
- No external dependencies (uses Python standard library only)
Inputs to Gather
Before running any scripts, collect from the user:
| Input | Description | Example |
|---|---|---|
| Parameter bounds | Min/max for each parameter with units | kappa: [0.1, 10.0] W/mK |
| Evaluation budget | Max number of simulations allowed | 50 runs |
| Noise level | Stochasticity of simulation outputs | low, medium, high |
| Constraints | Feasibility rules or forbidden regions | kappa + mobility < 5 |
Decision Guidance
Choosing a DOE Method
Is dimension <= 3 AND full coverage needed?
├── YES → Use factorial
└── NO → Is sensitivity analysis the goal?
├── YES → Use quasi-random (preferred; "sobol" is accepted but deprecated)
└── NO → Use lhs (Latin Hypercube)| Method | Best For | Avoid When |
|---|---|---|
lhs | General exploration, moderate dimensions (3-20) | Need exact grid coverage |
sobol | Sensitivity analysis, uniform coverage | Very high dimensions (>20) |
factorial | Low dimension (<4), need all corners | High dimension (exponential growth) |
Choosing an Optimizer
Is dimension <= 5 AND budget <= 100?
├── YES → Bayesian Optimization
└── NO → Is dimension <= 20?
├── YES → CMA-ES
└── NO → Random Search with screening| Noise Level | Recommendation |
|---|---|
| Low | Gradient-based if derivatives available, else Bayesian Optimization |
| Medium | Bayesian Optimization with noise model |
| High | Evolutionary algorithms or robust Bayesian Optimization |
Script Outputs (JSON Fields)
| Script | Output Fields |
|---|---|
scripts/doe_generator.py | samples, method, coverage |
scripts/optimizer_selector.py | recommended, expected_evals, notes |
scripts/sensitivity_summary.py | ranking, notes |
scripts/surrogate_builder.py | model_type, metrics, notes |
Workflow
1. Generate DOE with scripts/doe_generator.py 2. Run simulations at DOE sample points (user's responsibility) 3. Summarize sensitivity with scripts/sensitivity_summary.py 4. Choose optimizer using scripts/optimizer_selector.py 5. (Optional) Fit surrogate with scripts/surrogate_builder.py
CLI Examples
# Generate 20 LHS samples for 3 parameters
python3 scripts/doe_generator.py --params 3 --budget 20 --method lhs --json
# Rank parameters by sensitivity scores
python3 scripts/sensitivity_summary.py --scores 0.2,0.5,0.3 --names kappa,mobility,W --json
# Get optimizer recommendation for 3D problem with 50 eval budget
python3 scripts/optimizer_selector.py --dim 3 --budget 50 --noise low --json
# Build surrogate model from simulation data
python3 scripts/surrogate_builder.py --x 0,1,2 --y 10,12,15 --model rbf --jsonConversational Workflow Example
User: I need to calibrate thermal conductivity and diffusivity for my FEM simulation. I can run about 30 simulations.
Agent workflow: 1. Identify 2 parameters → --params 2 2. Budget is 30 → --budget 30 3. Use LHS for general exploration:
python3 scripts/doe_generator.py --params 2 --budget 30 --method lhs --json4. After user runs simulations and provides outputs, summarize sensitivity:
python3 scripts/sensitivity_summary.py --scores 0.7,0.3 --names conductivity,diffusivity --json5. Recommend optimizer:
python3 scripts/optimizer_selector.py --dim 2 --budget 30 --noise low --jsonError Handling
| Error | Cause | Resolution |
|---|---|---|
params must be positive | Zero or negative dimension | Ask user for valid parameter count |
budget must be positive | Zero or negative budget | Ask user for realistic simulation budget |
method must be lhs, sobol, or factorial | Invalid method | Use decision guidance to pick valid method |
scores must be comma-separated | Malformed input | Reformat as 0.1,0.2,0.3 |
Limitations
- Not for real-time optimization: Scripts provide recommendations, not live optimization loops
- Surrogate is a placeholder:
surrogate_builder.pycomputes basic metrics; replace with actual model for production - No automatic simulation execution: User must run simulations externally and provide results
References
references/doe_methods.md- Detailed DOE method comparisonreferences/optimizer_selection.md- Optimizer algorithm detailsreferences/sensitivity_guidelines.md- Sensitivity analysis interpretationreferences/surrogate_guidelines.md- Surrogate model selection
Version History
- v1.1.0 (2024-12-24): Enhanced documentation, decision guidance, conversational examples
- v1.0.0: Initial release with core scripts
Design of Experiments (DOE) Methods
Overview
Design of Experiments (DOE) creates sample points in parameter space to efficiently explore simulation behavior. The goal is to maximize information gained per simulation run.
Method Comparison
| Method | Sample Count | Space Coverage | Best Dimension | Deterministic |
|---|---|---|---|---|
| LHS | User-defined | Good | 3-20 | No (random) |
| Sobol | User-defined | Excellent | 2-15 | Yes |
| Factorial | k^d (levels^dim) | Complete | 1-3 | Yes |
---
Latin Hypercube Sampling (LHS)
How It Works
LHS divides each parameter range into n equal intervals, then places exactly one sample in each interval per dimension. This ensures no two samples share the same row or column in any 2D projection.
Example: 5 samples in 2D
1.0 | x | | | x |
0.8 | x | | | | |
0.6 | | | | x | |
0.4 | | | x | | |
0.2 | | x | | | |
+-----+-----+-----+-----+-----+
0.2 0.4 0.6 0.8 1.0When to Use
- General parameter exploration
- Moderate dimensions (3-20 parameters)
- Unknown response surface shape
- Limited simulation budget
When to Avoid
- Need exact corner/edge coverage
- Very low dimensions where factorial is feasible
- Reproducibility required (use fixed seed)
Sample Size Recommendations
| Dimension | Minimum Samples | Recommended |
|---|---|---|
| 2-3 | 10 | 20-30 |
| 4-6 | 20 | 40-60 |
| 7-10 | 30 | 60-100 |
| 11-20 | 50 | 100-200 |
---
Sobol Sequences (Quasi-Random)
How It Works
Sobol sequences are low-discrepancy sequences that fill space more uniformly than random sampling. Points are generated deterministically using bit operations on direction numbers.
Example: Sobol vs Random in 2D (16 points)
Sobol (uniform fill) Random (clusters/gaps)
+---+---+---+---+ +---+---+---+---+
| x | | x | | | | x | | x |
+---+---+---+---+ +---+---+---+---+
| | x | | x | | x | | | |
+---+---+---+---+ +---+---+---+---+
| x | | x | | | | x | x | x |
+---+---+---+---+ +---+---+---+---+
| | x | | x | | | | x | |
+---+---+---+---+ +---+---+---+---+When to Use
- Sensitivity analysis (Sobol indices)
- Need uniform coverage guarantees
- Reproducible experiments
- Sequential sampling (can add points incrementally)
When to Avoid
- Very high dimensions (>15, curse of dimensionality)
- Need stratified random sampling
Sample Size Recommendations
For Sobol sensitivity analysis, use N * (d + 2) samples where:
N= base sample size (64, 128, 256, 512, 1024)d= number of parameters
| Dimension | Base N | Total Samples |
|---|---|---|
| 3 | 64 | 320 |
| 5 | 128 | 896 |
| 10 | 256 | 3072 |
---
Full Factorial Design
How It Works
Factorial designs test all combinations of discrete parameter levels. For k levels across d dimensions, this produces k^d samples.
Example: 3 levels, 2 dimensions = 9 samples
High | x x x |
| |
Med | x x x |
| |
Low | x x x |
+-----------+
L M HWhen to Use
- Low dimensions (1-3 parameters)
- Need exact corner coverage
- Testing parameter interactions
- Screening designs
When to Avoid
- High dimensions (exponential growth)
- Continuous parameters with smooth response
- Limited budget
Sample Count Growth
| Dimension | 2 Levels | 3 Levels | 5 Levels |
|---|---|---|---|
| 2 | 4 | 9 | 25 |
| 3 | 8 | 27 | 125 |
| 4 | 16 | 81 | 625 |
| 5 | 32 | 243 | 3125 |
---
Decision Flowchart
START
|
v
Is d <= 3 AND need corner coverage?
|
+-- YES --> FACTORIAL
|
+-- NO --> Is sensitivity analysis the goal?
|
+-- YES --> SOBOL
|
+-- NO --> LHSImplementation Notes
The doe_generator.py script in this skill:
- Uses standard library only (no scipy/numpy required)
- LHS: True Latin Hypercube with random permutations
- Sobol: Simplified quasi-random (for full Sobol, use scipy.stats.qmc)
- Factorial: Full grid with level interpolation
Optimizer Selection Guide
Overview
Choosing the right optimization algorithm depends on problem characteristics: dimensionality, evaluation budget, noise level, and whether gradients are available.
Algorithm Comparison
| Algorithm | Best Dim | Min Budget | Noise Tolerance | Gradient Needed |
|---|---|---|---|---|
| Bayesian Optimization | 1-10 | 20 | Medium | No |
| CMA-ES | 5-100 | 50 | Low | No |
| Gradient Descent | Any | 10 | Very Low | Yes |
| Random Search | Any | 100+ | High | No |
| Nelder-Mead | 1-10 | 20 | Low | No |
---
Bayesian Optimization (BO)
How It Works
BO builds a probabilistic surrogate model (typically Gaussian Process) of the objective function and uses an acquisition function to balance exploration vs exploitation.
Iteration loop:
1. Fit GP to observed (x, y) pairs
2. Compute acquisition function (EI, UCB, PI)
3. Find x_next = argmax(acquisition)
4. Evaluate y_next = f(x_next)
5. Add (x_next, y_next) to dataset
6. Repeat until budget exhaustedWhen to Use
- Expensive simulations (minutes to hours per evaluation)
- Low to moderate dimensions (d <= 10)
- Smooth or moderately noisy objectives
- Small evaluation budgets (20-100)
When to Avoid
- High dimensions (d > 15) - GP scales as O(n^3)
- Very noisy objectives without noise model
- Fast evaluations where random search suffices
Key Hyperparameters
| Parameter | Typical Values | Notes |
|---|---|---|
| Kernel | Matern 5/2, RBF | Matern more robust for non-smooth |
| Acquisition | EI, UCB | EI for exploitation, UCB for exploration |
| Initial points | 5-10 | Use LHS or Sobol |
Libraries
botorch(PyTorch-based, production-ready)scikit-optimize(sklearn-compatible)GPyOpt(flexible but less maintained)
---
CMA-ES (Covariance Matrix Adaptation)
How It Works
CMA-ES is an evolutionary strategy that adapts the search distribution covariance matrix based on successful mutations.
Iteration loop:
1. Sample lambda offspring from N(m, sigma^2 * C)
2. Evaluate and rank offspring
3. Update mean m toward better solutions
4. Update covariance C and step-size sigma
5. Repeat until convergenceWhen to Use
- Moderate to high dimensions (5-100)
- Non-convex, multimodal landscapes
- No gradients available
- Budget of 100+ evaluations
When to Avoid
- Very small budgets (< 50)
- Low dimensions where BO is more efficient
- Highly noisy objectives
Key Hyperparameters
| Parameter | Typical Values | Notes |
|---|---|---|
| Population size | 4 + 3*ln(d) | Default is usually good |
| Initial sigma | 0.3 | Fraction of search range |
| Restarts | 1-5 | IPOP or BIPOP strategies |
Libraries
cma(official Python package)pycma(pure Python)nevergrad(includes CMA-ES)
---
Gradient-Based Methods
When to Use
- Gradients available (adjoint methods, autodiff)
- Smooth objectives with single optimum
- Very large dimensions
Algorithms
| Method | Order | Best For |
|---|---|---|
| L-BFGS-B | 2nd (approx) | Bounded problems |
| Adam | 1st | Stochastic objectives |
| Gradient Descent | 1st | Simple problems |
Convergence Criteria
Stop when ANY condition is met:
- ||grad|| < tol (gradient norm)
- |f_k - f_{k-1}| < ftol (function change)
- ||x_k - x_{k-1}|| < xtol (step size)
- k > max_iter (iteration limit)---
Random Search
How It Works
Sample uniformly at random from the parameter space and keep the best result.
When to Use
- Very high dimensions (d > 50)
- Highly noisy objectives
- Large budgets (1000+ evaluations)
- Baseline comparison
Efficiency Note
Random search with n samples finds a point in the top 1/n fraction with probability 1 - (1 - 1/n)^n ≈ 0.63.
---
Decision Flowchart
START
|
v
Are gradients available AND noise is low?
|
+-- YES --> GRADIENT-BASED (L-BFGS-B)
|
+-- NO --> Is dimension <= 10 AND budget <= 100?
|
+-- YES --> BAYESIAN OPTIMIZATION
|
+-- NO --> Is dimension <= 100?
|
+-- YES --> CMA-ES
|
+-- NO --> RANDOM SEARCHHandling Noise
| Noise Level | Recommendation |
|---|---|
| None | Any method works; prefer gradient if available |
| Low | BO with homoscedastic noise model |
| Medium | BO with heteroscedastic noise or CMA-ES with resampling |
| High | Robust BO, evolutionary strategies, or increase replicates |
Handling Constraints
| Constraint Type | Approach |
|---|---|
| Box bounds | Most optimizers support natively |
| Linear | Transform to box or use barrier methods |
| Nonlinear | Penalty methods or constrained BO |
| Black-box | Feasibility-aware acquisition (cEI) |
Expected Evaluation Counts
| Problem Type | Algorithm | Expected Evals to Converge |
|---|---|---|
| 3D smooth | BO | 20-40 |
| 5D smooth | BO | 40-80 |
| 10D multimodal | CMA-ES | 200-500 |
| 20D multimodal | CMA-ES | 500-2000 |
| 50D+ | Random/screening | 1000+ |
Implementation Notes
The optimizer_selector.py script in this skill provides recommendations based on:
- Dimension
- Budget
- Noise level
- Presence of constraints
It returns the most suitable algorithm(s) with expected evaluation counts and notes about configuration.
Sensitivity Analysis Guidelines
Overview
Sensitivity analysis quantifies how input parameter variations affect simulation outputs. It helps identify the most influential parameters for calibration and uncertainty reduction.
Method Categories
| Category | Purpose | Computational Cost |
|---|---|---|
| Local (OAT) | Derivative at a point | Low (d+1 evals) |
| Screening (Morris) | Rank parameters | Medium (r*(d+1) evals) |
| Global (Sobol) | Variance decomposition | High (N*(d+2) evals) |
---
Local Sensitivity (One-At-a-Time)
How It Works
Vary one parameter while holding others fixed at nominal values. Compute partial derivatives:
S_i = (dy/dx_i) * (x_i / y) [normalized]When to Use
- Quick screening
- Nearly linear response
- Local behavior near operating point
Limitations
- Misses parameter interactions
- Depends on chosen nominal point
- Invalid for nonlinear responses
---
Morris Method (Elementary Effects)
How It Works
Compute elementary effects by stepping through parameter space along random trajectories:
EE_i = [y(x + delta*e_i) - y(x)] / deltaStatistics computed:
mu*(mean absolute EE): Overall importancesigma(std of EE): Nonlinearity/interactions
Interpretation
| mu* | sigma | Interpretation |
|---|---|---|
| High | Low | Important, linear effect |
| High | High | Important, nonlinear or interacting |
| Low | Low | Unimportant |
| Low | High | Nonlinear but weak |
Sample Requirements
- Trajectories
r: 10-50 (typically 20) - Levels
p: 4-8 - Total evaluations:
r * (d + 1)
When to Use
- Moderate budgets
- Screening before detailed analysis
- Want to detect interactions
---
Sobol Indices (Variance-Based)
How It Works
Decompose output variance into contributions from each parameter and their interactions:
V(Y) = sum(V_i) + sum(V_ij) + ... + V_12...dIndices:
S_i(first-order): Main effect of parameter iS_Ti(total): Main + all interactions involving i
Interpretation
| S_i | S_Ti | Interpretation |
|---|---|---|
| ~0 | ~0 | Not influential |
| High | ~S_i | Mainly additive (linear) |
| Low | High | Important via interactions |
Sample Requirements
For Saltelli estimator:
- Base samples
N: 512, 1024, 2048 - Total evaluations:
N * (d + 2)
| Dimension | N | Total Evals |
|---|---|---|
| 3 | 512 | 2560 |
| 5 | 1024 | 7168 |
| 10 | 2048 | 24576 |
When to Use
- Quantitative variance attribution needed
- Sufficient budget for global analysis
- Nonlinear, interacting models
---
Interpreting Rankings
Score Thresholds
| Score Range | Interpretation |
|---|---|
| > 0.5 | Dominant parameter |
| 0.2 - 0.5 | Important parameter |
| 0.05 - 0.2 | Moderate influence |
| < 0.05 | Negligible |
When Rankings Are Close
If top parameters have similar scores: 1. Check for interactions (S_Ti >> S_i) 2. Consider fixing less important parameters 3. Use higher sample sizes for better precision
Red Flags
| Observation | Possible Cause |
|---|---|
| All scores near zero | Wrong output metric or insensitive region |
| Sum of S_i > 1 | Numerical error or strong negative correlations |
| S_Ti << S_i | Estimation error (impossible theoretically) |
---
Visualization Recommendations
Bar Charts
Plot parameters sorted by sensitivity score with confidence intervals.
kappa ████████████████████ 0.52
mobility ███████████ 0.28
W ██████ 0.15
rho ██ 0.05Interaction Heatmaps
For second-order indices S_ij, use heatmap with parameters on both axes.
Scatter Plots
Plot output vs each input to visually confirm sensitivity rankings.
---
Common Pitfalls
| Pitfall | Solution |
|---|---|
| Too few samples | Increase N; check confidence intervals |
| Ignoring interactions | Use total indices S_Ti, not just S_i |
| Wrong parameter ranges | Match realistic physical bounds |
| Correlated inputs | Use methods that handle correlations |
| Discrete parameters | Use Morris or specialized methods |
---
Implementation Notes
The sensitivity_summary.py script in this skill:
- Takes pre-computed sensitivity scores as input
- Ranks parameters from most to least influential
- Flags if all sensitivities are very low
- Returns structured JSON for downstream use
For computing Sobol indices, use external tools:
SALib(Python, comprehensive)sensitivity(R package)UQlab(MATLAB)
Surrogate Model Guidelines
Overview
Surrogate models (metamodels, emulators) approximate expensive simulations with fast-to-evaluate functions. They enable rapid optimization, sensitivity analysis, and uncertainty quantification.
Model Comparison
| Model | Complexity | Interpretable | Best Dimension | Handles Noise |
|---|---|---|---|---|
| Polynomial | Low | Yes | 1-5 | Poor |
| RBF | Medium | No | 1-20 | Poor |
| Gaussian Process | High | Partially | 1-15 | Yes |
| Neural Network | High | No | Any | Yes |
---
Polynomial Response Surface
How It Works
Fit polynomial of specified order to simulation data:
y = b0 + sum(b_i * x_i) + sum(b_ij * x_i * x_j) + ...Orders:
- Linear:
1 + dterms - Quadratic:
1 + d + d*(d+1)/2terms
When to Use
- Very limited data (< 20 points)
- Smooth, nearly quadratic response
- Need interpretable coefficients
- Quick approximation
When to Avoid
- Highly nonlinear responses
- Extrapolation required
- High dimensions (coefficient explosion)
Sample Requirements
| Order | Minimum Samples | Recommended |
|---|---|---|
| Linear | d + 1 | 2*(d+1) |
| Quadratic | (d+1)*(d+2)/2 | 2x minimum |
---
Radial Basis Functions (RBF)
How It Works
Interpolate using weighted sum of radial basis functions centered at data points:
y(x) = sum(w_i * phi(||x - x_i||))Common kernels:
- Gaussian:
exp(-r^2 / epsilon^2) - Multiquadric:
sqrt(1 + (epsilon*r)^2) - Thin-plate spline:
r^2 * log(r)
When to Use
- Exact interpolation required
- Moderate dimensions (< 20)
- No noise in data
- Complex response surfaces
When to Avoid
- Noisy data (will fit noise)
- Very large datasets (O(n^3) fitting)
- Need uncertainty estimates
Key Hyperparameters
| Parameter | Description | Tuning |
|---|---|---|
| epsilon | Width of basis function | Cross-validation or rule of thumb |
| Kernel type | Shape of basis | Try multiple, pick lowest CV error |
---
Gaussian Process (Kriging)
How It Works
Model output as realization of Gaussian Process with specified mean and covariance (kernel):
y(x) ~ GP(m(x), k(x, x'))Provides:
- Mean prediction: E[y(x)]
- Uncertainty: Var[y(x)]
When to Use
- Need uncertainty quantification
- Expensive simulations (BO framework)
- Smooth responses
- Sequential/adaptive sampling
When to Avoid
- Very large datasets (> 1000 points)
- High dimensions (> 15-20)
- Very fast simulations
Kernel Selection
| Kernel | Properties | Best For |
|---|---|---|
| RBF (SE) | Infinitely smooth | Very smooth responses |
| Matern 3/2 | Once differentiable | Typical engineering |
| Matern 5/2 | Twice differentiable | Default choice |
| Periodic | Captures periodicity | Cyclic phenomena |
Libraries
GPyTorch(PyTorch, scalable)GPy(numpy, flexible)scikit-learn(simple API)
---
Neural Networks
When to Use
- Very large datasets (> 10000 points)
- High dimensions
- Complex nonlinear patterns
- Have GPU resources
When to Avoid
- Small datasets (< 100 points)
- Need uncertainty (without extra work)
- Interpretability required
- Training time is limited
---
Validation Strategies
Cross-Validation
| Type | Procedure | When to Use |
|---|---|---|
| Leave-one-out | Predict each point from rest | Small datasets (< 50) |
| k-fold (k=5,10) | Split into k groups | Medium datasets |
| Hold-out | Reserve 20% for testing | Large datasets |
Metrics
| Metric | Formula | Target |
|---|---|---|
| RMSE | sqrt(mean((y - y_hat)^2)) | Lower is better |
| R^2 | 1 - SS_res/SS_tot | > 0.9 good, > 0.95 excellent |
| Max Error | max( | y - y_hat |
| NRMSE | RMSE / range(y) | < 5% good |
Red Flags
| Observation | Possible Cause |
|---|---|
| R^2 < 0.5 | Model too simple or data too noisy |
| Max error >> RMSE | Outliers or localized bad fit |
| Training error << CV error | Overfitting |
---
Adaptive Sampling
When initial surrogate is poor, add samples strategically:
| Strategy | How It Works |
|---|---|
| Max uncertainty | Sample where GP variance is highest |
| Max error | Sample where CV error is highest |
| Space-filling | Add LHS points to sparse regions |
| Exploitation | Sample near current optimum |
---
Decision Flowchart
START
|
v
Is data noisy?
|
+-- YES --> Need uncertainty?
| |
| +-- YES --> GAUSSIAN PROCESS
| |
| +-- NO --> NEURAL NETWORK (if large data)
|
+-- NO --> Is response smooth and low-dim?
|
+-- YES --> Is data < 20 points?
| |
| +-- YES --> POLYNOMIAL
| |
| +-- NO --> RBF or GP
|
+-- NO --> RBF or GP with Matern kernel---
Implementation Notes
The surrogate_builder.py script in this skill:
- Is a placeholder for demonstration
- Computes basic MSE metric only
- Does not fit actual models
For real surrogate modeling, use:
scikit-learn(polynomial, GP, neural networks)scipy.interpolate(RBF)GPyTorch(scalable GPs)SMT(Surrogate Modeling Toolbox)
#!/usr/bin/env python3
import argparse
import json
import random
import sys
import warnings
from typing import Dict, List
def lhs_samples(dim: int, budget: int, seed: int) -> List[List[float]]:
rng = random.Random(seed)
samples = []
for d in range(dim):
points = [(i + rng.random()) / budget for i in range(budget)]
rng.shuffle(points)
if d == 0:
samples = [[p] for p in points]
else:
for i, p in enumerate(points):
samples[i].append(p)
return samples
def quasi_random_samples(dim: int, budget: int, seed: int) -> List[List[float]]:
"""Generate quasi-random samples using additive recurrence.
Note: This is a simplified quasi-random sequence, not a true Sobol sequence.
For production use, consider scipy.stats.qmc.Sobol for actual Sobol sequences.
"""
rng = random.Random(seed)
# Use golden ratio based quasi-random for better uniformity than pure random
phi = (1 + 5 ** 0.5) / 2 # golden ratio
alpha = [((i + 1) * phi) % 1 for i in range(dim)]
samples = []
start = rng.random()
for n in range(budget):
point = [((start + (n + 1) * alpha[d]) % 1) for d in range(dim)]
samples.append(point)
return samples
def factorial_samples(dim: int, budget: int) -> List[List[float]]:
levels = int(round(budget ** (1.0 / dim)))
levels = max(levels, 2)
grid = [i / (levels - 1) for i in range(levels)]
samples = [[]]
for _ in range(dim):
samples = [s + [g] for s in samples for g in grid]
return samples[:budget]
def generate_doe(dim: int, budget: int, method: str, seed: int) -> Dict[str, object]:
if dim <= 0:
raise ValueError("params must be positive")
if budget <= 0:
raise ValueError("budget must be positive")
valid_methods = {"lhs", "sobol", "quasi-random", "factorial"}
if method not in valid_methods:
raise ValueError(f"method must be one of: {', '.join(sorted(valid_methods))}")
if method == "lhs":
samples = lhs_samples(dim, budget, seed)
elif method in {"sobol", "quasi-random"}:
if method == "sobol":
warnings.warn(
"Method 'sobol' is deprecated; use 'quasi-random' instead. "
"This is NOT a true Sobol sequence but a quasi-random additive recurrence.",
DeprecationWarning,
stacklevel=2,
)
samples = quasi_random_samples(dim, budget, seed)
else:
samples = factorial_samples(dim, budget)
return {
"method": method,
"samples": samples,
"coverage": {"count": len(samples), "dimension": dim},
}
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Generate design of experiments samples.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("--params", type=int, required=True, help="Number of parameters")
parser.add_argument("--budget", type=int, required=True, help="Sample budget")
parser.add_argument(
"--method",
choices=["lhs", "sobol", "quasi-random", "factorial"],
default="lhs",
help="DOE method (sobol uses quasi-random sequence)",
)
parser.add_argument("--seed", type=int, default=0, help="Random seed")
parser.add_argument("--json", action="store_true", help="Emit JSON output")
return parser.parse_args()
def main() -> None:
args = parse_args()
try:
result = generate_doe(args.params, args.budget, args.method, args.seed)
except ValueError as exc:
print(str(exc), file=sys.stderr)
sys.exit(2)
payload = {
"inputs": {
"params": args.params,
"budget": args.budget,
"method": args.method,
"seed": args.seed,
},
"results": result,
}
if args.json:
print(json.dumps(payload, indent=2, sort_keys=True))
return
print("DOE samples")
print(f" method: {result['method']}")
print(f" count: {result['coverage']['count']}")
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import argparse
import json
import sys
from typing import Dict, List
def select_optimizer(dim: int, budget: int, noise: str, constraints: bool) -> Dict[str, object]:
if dim <= 0:
raise ValueError("dim must be positive")
if budget <= 0:
raise ValueError("budget must be positive")
if noise not in {"low", "medium", "high"}:
raise ValueError("noise must be low, medium, or high")
recommended: List[str] = []
notes: List[str] = []
if dim <= 5 and budget <= 100:
recommended.append("Bayesian Optimization")
elif dim <= 20:
recommended.append("CMA-ES")
else:
recommended.append("Random Search")
if noise == "high":
notes.append("Use noise-aware acquisition or resampling.")
if constraints:
notes.append("Use constrained BO or penalty methods.")
expected = min(budget, max(20, dim * 10))
return {
"recommended": recommended,
"expected_evals": expected,
"notes": notes,
}
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Select optimization strategy for simulation calibration.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("--dim", type=int, required=True, help="Parameter dimension")
parser.add_argument("--budget", type=int, required=True, help="Evaluation budget")
parser.add_argument("--noise", choices=["low", "medium", "high"], default="low", help="Noise level")
parser.add_argument("--constraints", action="store_true", help="Constraints present")
parser.add_argument("--json", action="store_true", help="Emit JSON output")
return parser.parse_args()
def main() -> None:
args = parse_args()
try:
result = select_optimizer(args.dim, args.budget, args.noise, args.constraints)
except ValueError as exc:
print(str(exc), file=sys.stderr)
sys.exit(2)
payload = {
"inputs": {
"dim": args.dim,
"budget": args.budget,
"noise": args.noise,
"constraints": args.constraints,
},
"results": result,
}
if args.json:
print(json.dumps(payload, indent=2, sort_keys=True))
return
print("Optimizer selection")
print(f" recommended: {', '.join(result['recommended'])}")
print(f" expected_evals: {result['expected_evals']}")
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import argparse
import json
import sys
from typing import Dict, List
def parse_list(raw: str) -> List[float]:
parts = [p.strip() for p in raw.split(",") if p.strip()]
if not parts:
raise ValueError("scores must be a comma-separated list")
return [float(p) for p in parts]
def parse_names(raw: str, count: int) -> List[str]:
if not raw:
return [f"p{i+1}" for i in range(count)]
parts = [p.strip() for p in raw.split(",") if p.strip()]
if len(parts) != count:
raise ValueError("names count must match scores count")
return parts
def summarize(scores: List[float], names: List[str]) -> Dict[str, object]:
ranking = sorted(zip(names, scores), key=lambda x: x[1], reverse=True)
notes = []
if ranking and ranking[0][1] < 0.1:
notes.append("All sensitivities are low; consider alternative outputs.")
return {"ranking": ranking, "notes": notes}
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Summarize sensitivity scores and rank parameters.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("--scores", required=True, help="Comma-separated sensitivity scores")
parser.add_argument("--names", default=None, help="Comma-separated parameter names")
parser.add_argument("--json", action="store_true", help="Emit JSON output")
return parser.parse_args()
def main() -> None:
args = parse_args()
try:
scores = parse_list(args.scores)
names = parse_names(args.names, len(scores))
result = summarize(scores, names)
except ValueError as exc:
print(str(exc), file=sys.stderr)
sys.exit(2)
payload = {
"inputs": {
"scores": scores,
"names": names,
},
"results": result,
}
if args.json:
print(json.dumps(payload, indent=2, sort_keys=True))
return
print("Sensitivity summary")
for name, score in result["ranking"]:
print(f" {name}: {score:.6g}")
if __name__ == "__main__":
main()
#!/usr/bin/env python3
import argparse
import json
import sys
from typing import Dict, List
def parse_list(raw: str) -> List[float]:
parts = [p.strip() for p in raw.split(",") if p.strip()]
if not parts:
raise ValueError("value list must be a comma-separated list")
return [float(p) for p in parts]
def build_surrogate(x: List[float], y: List[float], model: str) -> Dict[str, object]:
if len(x) != len(y):
raise ValueError("x and y must have same length")
if model not in {"rbf", "poly"}:
raise ValueError("model must be rbf or poly")
if len(x) < 2:
raise ValueError("need at least 2 samples")
mean_y = sum(y) / len(y)
mse = sum((yi - mean_y) ** 2 for yi in y) / len(y)
return {
"model_type": model,
"metrics": {"mse": mse},
"notes": ["Surrogate is a placeholder; replace with real model."],
}
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Build a simple surrogate model summary.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument("--x", required=True, help="Comma-separated input values")
parser.add_argument("--y", required=True, help="Comma-separated output values")
parser.add_argument("--model", choices=["rbf", "poly"], default="rbf", help="Surrogate type")
parser.add_argument("--json", action="store_true", help="Emit JSON output")
return parser.parse_args()
def main() -> None:
args = parse_args()
try:
x = parse_list(args.x)
y = parse_list(args.y)
result = build_surrogate(x, y, args.model)
except ValueError as exc:
print(str(exc), file=sys.stderr)
sys.exit(2)
payload = {
"inputs": {"x": x, "y": y, "model": args.model},
"results": result,
}
if args.json:
print(json.dumps(payload, indent=2, sort_keys=True))
return
print("Surrogate summary")
print(f" model: {result['model_type']}")
print(f" mse: {result['metrics']['mse']:.6g}")
if __name__ == "__main__":
main()
Related skills
FAQ
Does it run my simulations?
No. The docs state there is no automatic simulation execution; the user runs simulations externally and provides results.
What dependencies are needed?
Python 3.8+ only; the scripts use the Python standard library with no external dependencies.