Skip to content

AutoSupervised

The one-object supervised entry point: AutoSupervised(config).fit(train_data) plans the feature-engineering recipe, fits the AutoGluon predictor and ml4's post-fit statistical layer, and returns a served FittedPipeline. See the supervised guide for a walkthrough.

recalibrate() is the one thing the façade does after a fit: it re-decides calibration, the decision threshold and the baseline gate together, in seconds, with no retraining. Anything richer than "which calibrator, what bar, on or off" goes through refit_decision_layer with an explicit config.

In short

  • AutoSupervised(config).fit(train_data) returns a FittedPipeline; the façade keeps it as pipeline_ and delegates predict / predict_proba / evaluate / save to it.
  • fit takes one training frame with the target inside it, plus optional label, models, path, events, cancel and mlops keywords.
  • recalibrate() re-decides the decision layer after a fit without retraining.
  • parleml_ml4.fit(config, train_df) and parleml_ml4.load_pipeline(path) are the one-call helpers.

AutoSupervised

AutoSupervised(
    config: Optional[Ml4Config] = None,
    *,
    path: Optional[str] = None
)

Fit a supervised ml4 pipeline from a config and a training frame.

The façade holds the :class:~parleml_ml4.config.Ml4Config and, after :meth:fit, the resulting :class:~parleml_ml4.delivery.fitted_pipeline.FittedPipeline (also returned by fit and available as :attr:pipeline_). predict / predict_proba / evaluate / save delegate to that pipeline.

fit

fit(
    train_data: DataFrame,
    *,
    label: Optional[str] = None,
    models: Optional[Tuple[StockModel, ...]] = None,
    path: Optional[str] = None,
    events: Optional[EventEmitter] = None,
    cancel: Optional["CancellationToken"] = None,
    mlops: Optional["MLOpsRunSettings"] = None
) -> FittedPipeline

Plan the FE recipe for train_data, fit the pipeline, and return it.

cancel (a :class:~parleml_ml4.telemetry.CancellationToken) makes a long fit interruptible: touch <dir>/CANCEL and AutoGluon is stopped gracefully between models, raising :class:~parleml_ml4.telemetry.CancelledError and leaving a resumable predictor. Without one the fit runs to completion uninterrupted.

label defaults to config.data.target_column.

models is the roster: a tuple of :data:~parleml_ml4.config.roster.StockModel specs. A gradient booster is named with the variant it trains — "GBM:gbdt", "GBM:dart", "GBM:rf", "CAT:symmetric", "XGB:gbtree" — and a family with one shipped variant is named bare ("RF", "LR", "NN_TORCH"). Two opt-in LightGBM specs come from AutoGluon's extreme_quality preset: "GBM:extra" (its settings) and the experimental "GBM:arith" (its arithmetic feature search); both read best beside "GBM:gbdt". Each entry is one more trained model, and one more Optuna study when config.hpo.provider="ml4_optuna"::

model.fit(train_df, models=("GBM:gbdt", "GBM:dart", "CAT:symmetric"))

Defaults to config.roster.models, and finally to :data:~parleml_ml4.config.roster.DEFAULT_MODELS — a single plain LightGBM.

events (an :class:~parleml_ml4.telemetry.EventEmitter) receives every supervised stage (:class:~parleml_ml4.telemetry.Stage) as stage_start / stage_end pairs, plus the run's warnings, for a progress UI: :func:~parleml_ml4.runner.fit_pipeline's, then registered, which spans the MLflow logging below — or is recorded skipped (disabled_by_config) when no MLflow logging was asked for, since then nothing registers the pipeline. Recipe planning runs before the first stage.

The single-model validation holdout is sized by :attr:~parleml_ml4.config.engine.Ml4EngineConfig.validation_holdout_frac on the config — it is not a fit argument, so a library caller and a product run resolve it identically.

mlops (opt-in) logs the fitted pipeline to MLflow through the hardened :func:parleml_ml4.delivery.mlflow_logging.log_pipeline — together with the run's non-default config as params and the fit-time headline measures as metrics — and, if configured, registers it (Unity Catalog included). The default None — and an empty :class:~parleml_ml4.mlops_settings.MLOpsRunSettings — log nothing. The run id is recorded on :attr:mlflow_run_id_.

predict

predict(X: DataFrame) -> Series

Deployed point predictions (calibrated + thresholded per task).

predict_proba

predict_proba(X: DataFrame) -> DataFrame

Class-probability frame (classification only).

evaluate

evaluate(
    X_test: DataFrame,
    y_test: Any,
    *,
    metric: Optional[EvalMetric] = None,
    bootstrap: int = 1000,
    cfg: Optional[Ml4Config] = None
) -> Dict[str, Any]

Fit-time measures + reported scores on a labelled test set.

Mirrors :func:parleml_ml4.evaluation.evaluate rather than forwarding **kwargs, so the options are discoverable from the façade a caller actually holds.

metric overrides the run's evaluation metric for this report; bootstrap is the resample count behind the headline score's 95% CI (0 skips it).

cfg defaults to this façade's config, which is what lets a beta / user_defined_metric run rebuild its real scorer for the headline instead of falling back to the task default and mislabelling the reported metric (DL-6). Pass it explicitly only to report against a different config than the one that trained.

When the fit logged to MLflow, this closes the loop MLF-3 opened: the reported scores are added to that same run as test_* metrics, beside the fit_* ones and the provenance tags that qualify them. There is no knob — :attr:mlflow_run_id_ is set only by a fit(mlops=...) that actually logged, so a façade that never logged writes nothing. Two evaluate calls on one façade both write to that run, which is the intended behaviour of a run that gets a second test set, not an accident: MLflow keeps both values and the compare-runs column shows the latest.

recalibrate

recalibrate(
    *,
    method: Optional[CalibrationMethod] = None,
    advantage_margin: Optional[float] = None,
    apply: Optional[bool] = None
) -> "AutoSupervised"

Re-decide the decision layer under different calibration settings, without retraining.

Deliberately narrow. Calibration is the setting anyone actually reaches for, and the three knobs here are the ones a user thinks in — which calibrator, what bar it has to clear, on or off. Everything else the layer reads (the metric, the seed, the gate's margin) is a property of the run rather than a choice about serving, and changing one of those from a convenience method would produce a layer the run's own numbers no longer describe. For those, build a :class:~parleml_ml4.delivery.decision_layer.DecisionLayerConfig and call :func:~parleml_ml4.delivery.decision_layer.refit_decision_layer explicitly.

The threshold and the baseline verdict are refitted with the calibration — they are one transaction, and a threshold left over from the previous calibrator is an operating point for a probability surface the model no longer serves.

Mutates the façade's pipeline in place and returns self for chaining::

model.recalibrate(method="temperature").save("out/bundle")

Raises :class:~parleml_ml4.delivery.decision_layer.DecisionLayerUnavailable when the run kept no basis, is not classification, or cannot rebuild its own scorer.

save

save(path: Optional[str] = None) -> str

Persist the served bundle; defaults to the façade's path.

Module-level helpers

fit

fit(
    config: Ml4Config,
    train_data: DataFrame,
    *,
    label: Optional[str] = None,
    models: Optional[Tuple[StockModel, ...]] = None,
    path: Optional[str] = None,
    events: Optional[EventEmitter] = None,
    cancel: Optional["CancellationToken"] = None,
    mlops: Optional["MLOpsRunSettings"] = None
) -> FittedPipeline

One-liner: fit a :class:FittedPipeline from a config and a training frame.

cancel makes the fit interruptible — see :meth:AutoSupervised.fit.

load_pipeline

load_pipeline(path: str) -> FittedPipeline

Reload a :class:FittedPipeline previously :meth:~AutoSupervised.save-d to path.

Next: FittedPipeline · Supervised learning