Recommender¶
Next-best-product recommendation built from calibrated one-vs-rest binary sub-models assembled into a comparable score matrix over the shared ranking surface. See the recommendation guide.
In short
Recommender(cfg).fit(df)trains the sub-models and stores the outcome onresult_.- Configure it with
parleml_ml4.config.recommendation.RecoConfig(entity, product and label columns, grain, negatives, gate). to_pipeline()returns theFittedRecoPipelineyou serve;route_cellsnames the sub-model behind each(entity, product)cell as aCellRoute.- Pass
outputs_dir=to persist the pipeline under<outputs_dir>/deploy/recommender/.
Recommender ¶
Recommender(
config: Optional[RecoConfig] = None,
*,
trainer: Optional[SubmodelTrainer] = None,
outputs_dir: Optional[str] = None,
setup_file_logger: bool = True
)
One-vs-Rest recommendation orchestrator.
Parameters¶
config:
Task configuration. Defaults to RecoConfig().
trainer:
Per-sub-model trainer (the seam to AutoSupervised). Defaults to
:class:~parleml_ml4.recommendation.trainer.AutoSupervisedTrainer with the
configured preset / overrides / calibration.
outputs_dir:
When set, opt into the events / cancel / deploy discipline (mirrors
:class:Forecaster): fit writes events.ndjson / manifest.json
and persists a :class:FittedRecoPipeline under
<outputs_dir>/deploy/recommender/.
The fitted pipeline¶
Recommender.to_pipeline() returns the deployable artefact: it scores, ranks, and
names the sub-model behind every (entity, product) cell (route_cells).
FittedRecoPipeline ¶
FittedRecoPipeline(
*,
ensemble: RecoEnsemble,
subcase_policy: SubcasePolicy,
config: RecoConfig,
result: RecoResult,
holdout: Optional[RecoHoldout] = None,
metadata: Optional[dict] = None
)
Self-contained, persistable One-vs-Rest recommendation artefact.
See docs/recommendation_ovr_plan.md §6.7.
config_feature_cols
property
¶
Feature columns the sub-models expect (recorded on the ensemble meta).
routing_states ¶
Per-class routing states for the entity frame X.
Raises when the ensemble was trained with an explicit subcase_col and
holds state-specific sub-models: that state cannot be recovered from an
entity-level frame, and scoring without it silently routes every cell to
one arbitrary expert per class. unified_only ensembles need
no states and pass through.
score_matrix ¶
Calibrated (len(X), n_classes) matrix (no objective transform).
X is one row per entity to score; it must carry the feature columns
and — when subcasing is enabled — the holdings column for routing.
route_cells ¶
route_cells(X: DataFrame) -> dict[str, CellRoute]
Which sub-model scores each (row, product) cell of X, and the holding.
The routing :meth:score_matrix applies, exposed per product so a consumer
that explains a cell (per-recommendation reasons) explains the sub-model that
actually scored it. holding reads the same holdings-derived state as
held / previously_held / not_held; it is None when the run has
no holdings column (or routes by an explicit subcase_col, whose states are
opaque), since then nothing says whether the entity holds the product.
recommend ¶
recommend(
X: DataFrame,
*,
n: Optional[int] = None,
objective: Optional[RankingObjective] = None,
shrinkage: Optional[bool] = None,
rank_percentile: bool = False,
popularity_discount: Optional[float] = None,
value_weights: Optional[Mapping[str, float]] = None,
value_alpha: float = 1.0
) -> dict[str, Any]
Return the calibrated matrix + top-N class names per entity.
objective defaults to the configured ranking_objective; the
calibrated probabilities stay available regardless of the sort key.
Two optional, post-training sort-key transforms (both off by default, so the default ranking applies neither):
shrinkage— apply Empirical-Bayes shrinkage toward each class's base rate (denoise small-sample classes).Noneuses the configuredshrinkage_strength(also off unless set);Trueforces it on with a sensible default;Falseforces it off.rank_percentile— rank within each class's own score distribution before sorting (scale/base-rate-invariant; favours rare classes).
popularity_discount (α) overrides the configured discount when set,
so a caller can preview an arbitrary point on the accuracy↔coverage knob
without re-fitting; None falls back to config.popularity_discount.
value_weights (per-product business/margin importance) tilts the
ranking toward high-value products — sort_key = score · weight **
value_alpha — applied after the relevance/objective transform.
Products absent from the map default to weight 1.0 (value-neutral),
so it is naturally the either/or counterpart to the popularity discount:
leave one neutral to use the other. Off by default.
CellRoute
dataclass
¶
How one product's cells of an entity frame are scored (see route_cells).
Next: Recommendation guide · LTRRanker