User Guide¶
What ddmo solves¶
Many optimization loops rely on expensive analyses such as CFD, FEM, or laboratory experiments. ddmo replaces repeated calls to the expensive function with a surrogate model fitted to sampled data:
Given a design matrix
the package fits a model \(\widehat{f}\) that can be queried cheaply for predictions, gradients, and quality metrics.
Installation¶
Core package¶
pip install -e .
Dashboard and docs extras¶
pip install -e ".[ui,docs,test]"
Basic workflow¶
Prepare an input matrix
Xwith shape(n_samples, n_features).Prepare a target vector
ywith shape(n_samples,).Fit one of the surrogate models.
Evaluate the model on held-out data.
Persist the fitted surrogate when needed.
import numpy as np
from ddmo import Kriging
rng = np.random.default_rng(0)
X = rng.uniform(-1.0, 1.0, size=(40, 2))
y = np.sin(3.0 * X[:, 0]) + X[:, 1] ** 2
model = Kriging().fit(X, y)
mean, std = model.predict(np.array([[0.2, -0.4]]), return_std=True)
grad = model.predict_gradient(np.array([[0.2, -0.4]]))
Backend execution flow¶
The dashboard backend orchestrates data loading, splitting, fitting, and ranking. At a high level, the workflow is:
Algorithm 1 Backend training and evaluation workflow
LaTeX source
\begin{algorithm}
\caption{Backend training and evaluation workflow}
\begin{algorithmic}[1]
\Require $D \in \mathbb{R}^{N \times q}$, feature columns $F$, target column $t$, models $\mathcal{M}$, hyperparameters $\Theta$, $\rho \in (0, 1)$, seed $s$, ranking weights $\alpha$
\Ensure $\mathcal{M}$ ordered by rank, fitted surrogates $\bigl(\widehat{f}_m\bigr)_{m \in \mathcal{M}}$
\State $X \gets D_{:,F}, \quad y \gets D_{:,t}$
\State $(X_{\mathrm{tr}}, X_{\mathrm{te}}, y_{\mathrm{tr}}, y_{\mathrm{te}}) \gets$ \Call{Split}{$X, y, \rho, s$}
\For{$m \in \mathcal{M}$}
\State $\widehat{f}_m \gets \mathcal{A}_m(\Theta)(X_{\mathrm{tr}}, y_{\mathrm{tr}})$
\State $e^{\mathrm{tr}} \gets y_{\mathrm{tr}} - \widehat{f}_m(X_{\mathrm{tr}}), \quad e^{\mathrm{te}} \gets y_{\mathrm{te}} - \widehat{f}_m(X_{\mathrm{te}})$
\State $\mathrm{RMSE}^{\mathrm{te}}_m \gets \lVert e^{\mathrm{te}} \rVert_2 / \sqrt{n_{\mathrm{te}}}, \quad \mathrm{MAE}^{\mathrm{te}}_m \gets \lVert e^{\mathrm{te}} \rVert_1 / n_{\mathrm{te}}$
\State $R^2_m \gets 1 - \dfrac{\lVert e^{\mathrm{te}} \rVert_2^2}{\lVert y_{\mathrm{te}} - \bar{y}_{\mathrm{te}}\mathbf{1} \rVert_2^2}, \quad R^2_{\mathrm{pred},m} \gets 1 - \dfrac{\lVert e^{\mathrm{te}} \rVert_2^2}{\lVert y_{\mathrm{te}} - \bar{y}_{\mathrm{tr}}\mathbf{1} \rVert_2^2}$
\State $\Delta_m \gets \mathrm{RMSE}^{\mathrm{te}}_m - \mathrm{RMSE}^{\mathrm{tr}}_m, \quad R^2_{\mathrm{cv},m} \gets$ \Call{OutOfFoldR2}{$m, X_{\mathrm{tr}}, y_{\mathrm{tr}}$}
\EndFor
\If{ranking is weighted composite}
\State $p_k(m) \gets \dfrac{v_k(m) - \min_{m'} v_k(m')}{\max_{m'} v_k(m') - \min_{m'} v_k(m')}$ \Comment{use $1 - p_k$ if higher is better}
\State sort $\mathcal{M}$ by $S_m = \sum_k \alpha_k\, p_k(m) \,/\, \sum_k \alpha_k$ ascending
\Else
\State sort $\mathcal{M}$ lexicographically by $\bigl(\mathrm{RMSE}^{\mathrm{te}}_m,\ \mathrm{MAE}^{\mathrm{te}}_m,\ -R^2_m,\ -R^2_{\mathrm{pred},m},\ |\Delta_m|\bigr)$
\EndIf
\State \Return $\mathcal{M}$, $\bigl(\widehat{f}_m\bigr)_{m \in \mathcal{M}}$
\end{algorithmic}
\end{algorithm}
Running the dashboard¶
ddmo-dashboard
The dashboard allows you to upload CSV data, choose feature and target columns, compare multiple models, and export the best fitted model for downstream use.
Persisting a trained model¶
from ddmo import save_model, load_model
save_model(model, "kriging_model.pkl", feature_names=["x0", "x1"], target_name="y")
bundle = load_model("kriging_model.pkl")
prediction = bundle.predict(X)
When to choose each model¶
LS: smooth global trends, response surfaces, and sparse polynomial structure.RBF: exact interpolation with fast fitting and flexible kernels.Kriging: interpolation plus uncertainty estimation.WeightedEnsemble: blended predictions when no single surrogate family dominates.