mixle.evolve.operators module

The propose contract: a uniform ImprovementOperator over existing fit mechanisms.

Every “improve” move – a warm-start refit, an online update, an auto-select, a recalibration – is one operator with the same shape, so they become interchangeable proposal moves the driver can schedule and the gate can compare. Each operator body is a thin shell over a verified-present API:

  • Refit -> mixle.inference.estimation.optimize() warm-started from the champion.

  • OnlineUpdate -> the streaming estimators (StreamingEstimator / IncrementalEstimator

    / BayesianStreamingEstimator) .update.

  • AutoSelect -> mixle.utils.automatic.get_estimator() -> optimize.

  • Recalibrate -> a post-hoc affine spread-temperature wrap that recalibrates the predictive

    without refitting the base parameters.

Operators are registrable through a scoped registry (register_operator / unregister_operator) that mirrors the “register, don’t branch” pattern without polluting the global Detector registry.

class ImprovementOperator(*args, **kwargs)[source]

Bases: Protocol

A uniform proposal move: an applicability pre-flight plus a fitted-challenger propose.

applicable(model, data, *, ctx)[source]

Structural gate: whether this operator can run on the model and data.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Return a fitted challenger (or raise if the proposal cannot be built).

Parameters:
Return type:

Candidate

class Candidate(model, operator, parent_hash=None, meta=<factory>)[source]

Bases: object

A proposed, already-fitted challenger plus the provenance of how it was made.

Parameters:
  • model (Any)

  • operator (str)

  • parent_hash (str | None)

  • meta (dict)

class Refit(name='refit', cost_hint=1.0, max_its=20)[source]

Bases: object

Re-fit the champion’s family on fresh data, warm-started from the champion’s parameters.

Parameters:
applicable(model, data, *, ctx)[source]

Return whether model can be re-fit on a non-empty batch.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Fit the model family on data using model as the warm start.

Parameters:
Return type:

Candidate

class OnlineUpdate(mode='streaming', cost_hint=0.2)[source]

Bases: object

Fold a fresh batch into the champion via a streaming estimator.

mode:
  • 'streaming' – decay-mode StreamingEstimator (running-accumulator forgetting).

  • 'incremental' – Neal-Hinton IncrementalEstimator (replace one chunk).

  • 'posterior_carry' – exact recursive-Bayes BayesianStreamingEstimator (needs a

    conjugate family; applicable checks ConjugateUpdatable).

  • 'forgetting' – power-prior BayesianStreamingEstimator.

Parameters:
property name: str

Registry name including the selected online-update mode.

applicable(model, data, *, ctx)[source]

Return whether the selected update mode is legal for model and data.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Apply the selected streaming update and return the updated challenger.

Parameters:
Return type:

Candidate

class AutoSelect(name='auto_select', cost_hint=3.0, max_its=20)[source]

Bases: object

Infer an estimator from the raw data (get_estimator) and fit it – a possible family swap.

Parameters:
applicable(model, data, *, ctx)[source]

Return whether there is data available for automatic family selection.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Infer an estimator from data, fit it, and return the fitted challenger.

Parameters:
Return type:

Candidate

class Recalibrate(name='recalibrate', cost_hint=0.5, ensemble=256, seed=0, grid=(0.6, 0.75, 0.9, 1.0, 1.1, 1.25, 1.5, 2.0))[source]

Bases: object

Learn a predictive spread temperature T that flattens the PIT, no parameter refit.

applicable requires a sampler (used both to estimate the predictive center and to evaluate PIT calibration). The temperature is chosen on the train split by minimising the PIT calibration error over a small grid; T == 1 (the identity) is always in the grid, so the recalibrated model can never be worse-calibrated than the base on the fitting data.

Parameters:
applicable(model, data, *, ctx)[source]

Return whether model can be sampled and the batch is non-empty.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Search the temperature grid and wrap model in the best calibration transform.

Parameters:
Return type:

Candidate

class Recompose(name='recompose', cost_hint=4.0, max_its=30)[source]

Bases: object

Propose a richer two-component mixture structure for the champion family.

Each component is warm-fit on a different half of the data so EM starts away from the identical-component solution. The normal verification gate decides whether the additional structure improves held-out evidence enough to promote. The operator is registered but omitted from the default set because it is intentionally more expensive than the conservative updates.

Parameters:
applicable(model, data, *, ctx)[source]

Return whether the model can be re-estimated on enough rows for a split.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Fit a two-component mixture challenger initialized from data splits.

Parameters:
Return type:

Candidate

class Mutate(name='mutate', cost_hint=4.0, max_its=30)[source]

Bases: object

Apply a random structural mutation to the champion and refit.

Available moves are grow for adding a bootstrap-fit component, shrink for dropping the lowest-weight component from an existing mixture, and perturb for a bootstrap re-fit. Repeated use inside a Population gives the search driver a structure-induction move, while the verification gate remains responsible for promotion. The operator is registered but omitted from the default set because it is comparatively expensive.

Parameters:
applicable(model, data, *, ctx)[source]

Return whether the model can be structurally mutated and re-fit.

Parameters:
Return type:

bool

propose(model, data, *, ctx)[source]

Sample one structural move, refit it, and return the resulting challenger.

Parameters:
Return type:

Candidate

register_operator(operator)[source]

Register operator in the scoped evolve operator registry (returns it for decorator use).

Parameters:

operator (ImprovementOperator)

Return type:

ImprovementOperator

unregister_operator(name)[source]

Remove a previously-registered operator by name (no-op if absent).

Parameters:

name (str)

Return type:

None

registered_operators()[source]

A copy of the current scoped operator registry.

Return type:

dict[str, ImprovementOperator]

default_operators()[source]

The Phase-1 default operator set: refit, online update, auto-select, recalibrate. (Recompose + Mutate are structural + expensive, so they are available via the registry but not enabled by default.)

Return type:

list[ImprovementOperator]