jaxsr.regressor#
Main SymbolicRegressor Class for JAXSR.
Provides a scikit-learn compatible interface for symbolic regression.
- class jaxsr.regressor.SymbolicRegressor(basis_library: BasisLibrary | None = None, max_terms: int = 5, strategy: str = 'greedy_forward', information_criterion: str = 'bic', cv_folds: int = 5, regularization: float | None = None, constraints: Constraints | None = None, random_state: int | None = None, param_optimizer: str = 'scipy', param_optimization_budget: int = 50, constraint_enforcement: str = 'penalty', constraint_selection_weight: float = 0.0, prune_tol: float = 1e-06)#
Bases:
_SklearnCompatMixinJAX-accelerated symbolic regression using sparse selection.
Discovers interpretable algebraic expressions from data by selecting sparse subsets of basis functions using information criteria.
- Parameters:
basis_library (BasisLibrary, optional) – Library of candidate basis functions. If None, must be specified when calling fit() via the library_config parameter.
max_terms (int) – Maximum number of terms in the expression.
strategy (str) – Selection strategy: “greedy_forward”, “greedy_backward”, “exhaustive”, or “lasso_path”.
information_criterion (str) – Criterion for model selection: “aic”, “aicc”, “bic”.
cv_folds (int) – Number of cross-validation folds (if using CV for selection).
regularization (float, optional) – L2 regularization parameter (ridge penalty).
constraints (Constraints, optional) – Physical constraints to enforce.
random_state (int, optional) – Random seed for reproducibility.
constraint_selection_weight (float) – Weight for constraint penalty during model selection. When > 0, a penalty proportional to constraint violations is added to the information criterion during term selection, biasing selection towards models that better satisfy constraints. Default 0.0 (no constraint-aware selection).
prune_tol (float) – After fitting, drop any selected term whose contribution to the fit (
|coef| * ||basis||on the training data) is smaller thanprune_toltimes the largest term’s contribution, then refit. This removes numerically negligible terms and prevents a spuriously selected basis that diverges out of the training domain (e.g.exp(x0/x1)nearx1 = 0) from makingpredictnon-finite. Set to 0 to disable. Default 1e-6.
- expression_#
Human-readable expression after fitting.
- Type:
str
- coefficients_#
Fitted coefficients.
- Type:
jnp.ndarray
- selected_features_#
Names of selected basis functions.
- Type:
list of str
- complexity_#
Total complexity score of the expression.
- Type:
int
- metrics_#
Dictionary of evaluation metrics.
- Type:
dict
- pareto_front_#
Pareto-optimal models.
- Type:
list of SelectionResult
Examples
>>> from jaxsr import BasisLibrary, SymbolicRegressor >>> library = (BasisLibrary(n_features=2) ... .add_constant() ... .add_linear() ... .add_polynomials(max_degree=3) ... ) >>> model = SymbolicRegressor(basis_library=library, max_terms=5) >>> model.fit(X, y) >>> print(model.expression_) >>> y_pred = model.predict(X_new)
- property expression_: str#
Human-readable expression.
- property coefficients_: Array#
Fitted coefficients.
- property selected_features_: list[str]#
Names of selected basis functions.
- property selected_indices_: Array#
Indices of selected basis functions.
- property complexity_: int#
Total complexity score.
- property metrics_: dict[str, float]#
Evaluation metrics (weighted when the model was fitted with weights).
- property sample_weight_: Array | None#
Normalised training weights, or
Noneif the fit was unweighted.- Returns:
Weights of shape
(n_samples,)scaled to sum ton_samples. These are the weights actually used, not the array passed tofit()– only the ratios between weights carry meaning.- Return type:
jnp.ndarray or None
- Raises:
RuntimeError – If the model has not been fitted.
- property effective_sample_size_: float#
Kish effective sample size of the training weights.
- Returns:
(sum w)^2 / sum w^2, equal tonfor an unweighted fit and smaller when the weights are uneven.- Return type:
float
- Raises:
RuntimeError – If the model has not been fitted.
Notes
This is a diagnostic, not an input: AIC/BIC/AICc use the nominal
n(seejaxsr.metrics.compute_information_criterion()). When this number is far belown, the criteria are comparing models on much less information thannsuggests, and the usual asymptotic intuitions about BIC’s penalty are correspondingly weaker.
- property pareto_front_: list[SelectionResult]#
Pareto-optimal models.
- property selection_path_: SelectionPath#
Every candidate model the search evaluated, with the winner marked.
- Returns:
Holds
results(a list ofSelectionResult, each carrying its own coefficients, MSE, complexity and AIC/BIC/AICc), thestrategyname, andbest_index– the entry chosen by the configuredinformation_criterion.- Return type:
- Raises:
RuntimeError – If the model has not been fitted.
Notes
What
resultscontains depends on the strategy. The greedy searches record one model per step, so the path reads as “best model of each size”.exhaustiverecords every subset it evaluated, so ranking the path by an information criterion is meaningful there. Usepareto_front_for the accuracy/complexity trade-off curve.The path records the search as it happened, before the post-selection steps in
fit()– dropping non-finite terms, pruning negligible ones underprune_tol, and constraint refitting. Sopath.bestcan carry more terms thanselected_features_; the fitted model is always a subset of it. Read the final model fromcoefficients_andselected_features_, not from the path.Examples
>>> model = SymbolicRegressor(basis_library=library).fit(X, y) >>> path = model.selection_path_ >>> for i, r in enumerate(path.results): ... mark = "*" if i == path.best_index else " " ... print(f"{mark} {r.n_terms} terms BIC={r.bic:.1f} {r.expression()}")
- fit(X: Array, y: Array, sample_weight: Array | None = None) SymbolicRegressor#
Fit symbolic regression model.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Training data.
y (array-like of shape (n_samples,)) – Target values.
sample_weight (array-like of shape (n_samples,), optional) – Per-sample weights. Observation
iis treated as having variancesigma^2 / w_i, so the fit minimisessum_i w_i (y_i - f(x_i))^2. Typical sources are measurement variances (w = 1 / var), replicate counts, or a smooth taper that de-emphasises rows carrying little information.
- Returns:
self – Fitted model.
- Return type:
- Raises:
ValueError – If
Xandydisagree on the number of samples, ifbasis_libraryis not set, ifXhas the wrong number of features, or ifsample_weighthas the wrong length or contains negative or non-finite values.
Notes
Weights are used consistently, not just for the final coefficients: term selection, the reported MSE, AIC/BIC/AICc, constraint refitting, R², the classical intervals and the bootstrap all run on the weighted problem.
Only the ratios between weights matter. They are normalised to average 1 internally, so
w,2 * wandw / 1000all give the same model and the same information criteria, and the effective sample size in AIC/BIC stays the nominaln. Weighting therefore never manufactures observations – which is also why duplicating rows is not an equivalent trick: it inflatesnand shifts every criterion. Seeeffective_sample_size_for a diagnostic of how much information the weights actually leave.A weight of exactly 0 excludes a row from the fit while keeping it in
n. If you mean to drop the row entirely, drop it fromXandyinstead.Examples
>>> variances = np.array([0.1, 0.1, 4.0, 4.0]) >>> model.fit(X, y, sample_weight=1.0 / variances)
- predict(X: Array) Array#
Predict using fitted model.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Samples to predict.
- Returns:
y_pred – Predicted values.
- Return type:
jnp.ndarray of shape (n_samples,)
- score(X: Array, y: Array, sample_weight: Array | None = None) float#
Compute R² score.
- Parameters:
X (array-like) – Test samples.
y (array-like) – True values.
sample_weight (array-like of shape (n_samples,), optional) – Weights for these samples. Not inherited from
fit()–Xandyhere are usually different data, so their weights have to come with them.
- Returns:
score – (Weighted) R² score.
- Return type:
float
- Raises:
RuntimeError – If the model has not been fitted.
ValueError – If
sample_weightis invalid.
- property sigma_: float#
sqrt(SSR / (n - p)).
- Returns:
sigma – Noise standard deviation estimate. Under sample weights this is the noise level of a unit-weight observation: row
iis modelled with variancesigma^2 / w_i.- Return type:
float
- Type:
Estimated noise standard deviation
- property covariance_matrix_: Array#
s^2 * (Phi^T W Phi)^{-1}.
- Returns:
cov – Covariance matrix of shape (p, p).
Wis the diagonal matrix of training weights (the identity for an unweighted fit).- Return type:
jnp.ndarray
- Type:
Coefficient covariance matrix
- coefficient_intervals(alpha: float = 0.05) dict[str, tuple]#
Confidence intervals for all coefficients.
- Parameters:
alpha (float) – Significance level (default 0.05 for 95% CIs).
- Returns:
intervals – {name: (estimate, lower, upper, se)} for each coefficient. Standard errors come from the weighted covariance matrix when the model was fitted with
sample_weight.- Return type:
dict
- predict_interval(X: Array, alpha: float = 0.05) tuple[Array, Array, Array]#
Prediction intervals for new observations.
- Parameters:
X (jnp.ndarray) – New input data of shape (n_samples, n_features).
alpha (float) – Significance level (default 0.05 for 95% intervals).
- Returns:
y_pred (jnp.ndarray) – Predicted values.
lower (jnp.ndarray) – Lower prediction interval bound.
upper (jnp.ndarray) – Upper prediction interval bound.
Notes
For a weighted fit the interval is for a new observation of unit weight, i.e. one measured as precisely as an average training point. Rescale by
1 / sqrt(w_new)if the new observation has a known precision of its own.
- confidence_band(X: Array, alpha: float = 0.05) tuple[Array, Array, Array]#
Confidence band on mean response E[y|x].
- Parameters:
X (jnp.ndarray) – New input data of shape (n_samples, n_features).
alpha (float) – Significance level (default 0.05 for 95% band).
- Returns:
y_pred (jnp.ndarray) – Predicted mean values.
lower (jnp.ndarray) – Lower confidence band bound.
upper (jnp.ndarray) – Upper confidence band bound.
- predict_ensemble(X: Array) dict[str, Any]#
Predictions from Pareto-front models.
- Parameters:
X (jnp.ndarray) – New input data.
- Returns:
result – Keys: y_mean, y_std, y_min, y_max, y_all, models.
- Return type:
dict
- predict_bma(X: Array, criterion: str = 'bic', alpha: float = 0.05) tuple[Array, Array, Array]#
Bayesian Model Averaging prediction with intervals.
- Parameters:
X (jnp.ndarray) – New input data.
criterion (str) – IC for weighting (“bic” or “aic”).
alpha (float) – Significance level.
- Returns:
y_pred (jnp.ndarray) – BMA mean prediction.
lower (jnp.ndarray) – Lower bound.
upper (jnp.ndarray) – Upper bound.
- predict_conformal(X: Array, alpha: float = 0.05, method: str = 'jackknife+', X_cal: Array | None = None, y_cal: Array | None = None) tuple[Array, Array, Array]#
Conformal prediction intervals.
- Parameters:
X (jnp.ndarray) – New input data.
alpha (float) – Significance level.
method (str) – “jackknife+” or “split”.
X_cal (jnp.ndarray, optional) – Calibration features (required for “split” method).
y_cal (jnp.ndarray, optional) – Calibration targets (required for “split” method).
- Returns:
y_pred (jnp.ndarray) – Point predictions.
lower (jnp.ndarray) – Lower interval bound.
upper (jnp.ndarray) – Upper interval bound.
- update(X_new: Array, y_new: Array, refit: bool = True, sample_weight_new: Array | None = None) SymbolicRegressor#
Update model with new data points.
- Parameters:
X_new (array-like) – New input samples.
y_new (array-like) – New target values.
refit (bool) – If True, rerun full selection. If False, only refit coefficients.
sample_weight_new (array-like of shape (n_new,), optional) – Weights for the new samples, on the same scale as the weights passed to
fit(). Defaults to 1 per new sample. Omitting it for a weighted model therefore adds the new points at unit weight, which is what “as precise as an average existing point” means.
- Returns:
self – Updated model.
- Return type:
- Raises:
RuntimeError – If the model has not been fitted.
ValueError – If
sample_weight_newhas the wrong length or contains negative or non-finite values.
- to_sympy()#
Convert expression to SymPy for symbolic manipulation.
- Returns:
expr – SymPy expression.
- Return type:
sympy.Expr
- to_latex() str#
Convert expression to LaTeX string.
- Returns:
latex – LaTeX representation.
- Return type:
str
- to_callable() Callable[[ndarray], ndarray]#
Convert to pure Python/NumPy callable (no JAX dependency).
- Returns:
func – Function that takes NumPy array and returns predictions.
- Return type:
callable
- save(filepath: str) None#
Save model to JSON file.
- Parameters:
filepath (str) – Path to save the model.
- classmethod load(filepath: str) SymbolicRegressor#
Load model from JSON file.
- Parameters:
filepath (str) – Path to the model file.
- Returns:
model – Loaded model.
- Return type:
- summary() str#
Return a summary of the fitted model.
- Returns:
summary – Model summary.
- Return type:
str
- class jaxsr.regressor.MultiOutputSymbolicRegressor(estimator: SymbolicRegressor, target_names: list[str] | None = None)#
Bases:
_SklearnCompatMixinMulti-output symbolic regression via per-column fitting.
Wraps a
SymbolicRegressortemplate and clones it once per output column, discovering a separate algebraic expression for each target.- Parameters:
estimator (SymbolicRegressor) – Template estimator whose configuration is cloned for every output.
target_names (list of str, optional) – Human-readable names for each output column. If
None, defaults to["y0", "y1", ...].
- estimators_#
Fitted estimators (one per output column).
- Type:
list of SymbolicRegressor
- expressions_#
Discovered expressions (one per output column).
- Type:
list of str
- n_outputs_#
Number of output columns.
- Type:
int
- target_names_#
Resolved target names.
- Type:
list of str
Examples
>>> from jaxsr import BasisLibrary, SymbolicRegressor, MultiOutputSymbolicRegressor >>> lib = BasisLibrary(n_features=2).add_constant().add_linear().add_polynomials(2) >>> template = SymbolicRegressor(basis_library=lib, max_terms=4) >>> mo = MultiOutputSymbolicRegressor(template) >>> mo.fit(X, Y) # Y has shape (n, m) >>> Y_pred = mo.predict(X) # shape (n, m)
- property estimators_: list[SymbolicRegressor]#
Fitted per-output estimators.
- property expressions_: list[str]#
Discovered expressions (one per output).
- property n_outputs_: int#
Number of output columns.
- property target_names_: list[str]#
Resolved target names.
- fit(X: Array, y: Array, sample_weight: Array | None = None) MultiOutputSymbolicRegressor#
Fit one symbolic regressor per output column.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Training data.
y (array-like of shape (n_samples, n_outputs)) – Target matrix. Must be 2-D; for single-output problems use
SymbolicRegressordirectly.sample_weight (array-like of shape (n_samples,), optional) – Per-sample weights, shared by every output. Weights that differ per output are not supported here – fit separate
SymbolicRegressorinstances for that.
- Returns:
self – Fitted model.
- Return type:
- Raises:
ValueError – If
yis not 2-D, if shapes are inconsistent, iftarget_nameslength does not match the number of columns, or ifsample_weightis invalid.
- predict(X: Array) Array#
Predict all outputs.
- Parameters:
X (array-like of shape (n_samples, n_features)) – Samples to predict.
- Returns:
y_pred – Predicted values.
- Return type:
jnp.ndarray of shape (n_samples, n_outputs)
- score(X: Array, y: Array) float#
Mean R² across all outputs (sklearn convention).
- Parameters:
X (array-like) – Test samples.
y (array-like of shape (n_samples, n_outputs)) – True values.
- Returns:
score – Mean R² across outputs.
- Return type:
float
- to_sympy() list#
Convert each output’s expression to SymPy.
- Returns:
exprs – One SymPy expression per output.
- Return type:
list of sympy.Expr
- to_latex() list[str]#
Convert each output’s expression to LaTeX.
- Returns:
latex_strs – One LaTeX string per output.
- Return type:
list of str
- to_callable() Callable[[ndarray], ndarray]#
Return a pure NumPy callable that predicts all outputs.
- Returns:
func – Function
(n, d) -> (n, m)using NumPy only.- Return type:
callable
- summary() str#
Return a combined summary of all per-output models.
- Returns:
summary – Concatenated summaries.
- Return type:
str
- save(filepath: str) None#
Save multi-output model to JSON file.
- Parameters:
filepath (str) – Path to save the model.
- classmethod load(filepath: str) MultiOutputSymbolicRegressor#
Load multi-output model from JSON file.
- Parameters:
filepath (str) – Path to the model file.
- Returns:
model – Loaded model.
- Return type:
- jaxsr.regressor.fit_symbolic(X: Array, y: Array, feature_names: list[str] | None = None, max_terms: int = 5, max_poly_degree: int = 3, include_transcendental: bool = True, include_ratios: bool = False, strategy: str = 'greedy_forward', information_criterion: str = 'bic', sample_weight: Array | None = None) SymbolicRegressor#
Convenience function for quick symbolic regression.
- Parameters:
X (array-like) – Input features.
y (array-like) – Target values.
feature_names (list of str, optional) – Names for features.
max_terms (int) – Maximum terms in expression.
max_poly_degree (int) – Maximum polynomial degree.
include_transcendental (bool) – Include log, exp, sqrt, inv.
include_ratios (bool) – Include x_i / x_j terms.
strategy (str) – Selection strategy.
information_criterion (str) – Information criterion.
sample_weight (array-like of shape (n_samples,), optional) – Per-sample weights; see
SymbolicRegressor.fit().
- Returns:
model – Fitted model.
- Return type:
- Raises:
ValueError – If
sample_weightis invalid.
Examples
>>> model = fit_symbolic(X, y, feature_names=["T", "P"]) >>> print(model.expression_)