pytyche.experiment.sequential¶
The SequentialExperiment state machine — the L1 round-by-round loop.
Each advance() (equivalently next(exp)) runs one round: size the
round from the schedule, hand the current
NextRoundPlan to the
generator, fit the joint hurdle BCF on the CUMULATIVE data, analyze,
score the round’s cells, ask the recommendation engine for the next
plan, and (sim mode) evaluate against the cumulative ground truth. All
state commits atomically at the end of the round — a failed step leaves
history untouched.
The cumulative row order is variant-major: all rounds of the first-seen
variant, then all rounds of the next. Per-round artifacts aligned to a
round’s own concatenation (truth arrays, the cell column) are
re-indexed into that order via the position map _build_cumulative
returns.
Module Attributes
The single data-source contract. |
Functions
|
Construct a |
Classes
|
Stateful round-by-round adaptive experiment loop. |
Exceptions
Emitted once per |
- pytyche.experiment.sequential.Generator[source]¶
The single data-source contract. The loop invokes
generator(round_idx, plan)at the start of each round and receives(observed, truth)—truthis non-None in sim mode andNonein real-data mode (the mode may not flip between rounds). Every returned visitors frame must carry the reservedcellcolumn recording each visitor’s allocated cell id, and generators assigning adaptively record per-visitor propensities in the reserved propensity columns (propensityat K = 2,propensity_1..propensity_{K-1}at K >= 3).alias of
Callable[[int,NextRoundPlan],tuple[ObservedExperimentData,CalibrationTruth|None]]
- exception pytyche.experiment.sequential.UncalibratedWarning[source]¶
Bases:
UserWarningEmitted once per
SequentialExperimentrunning uncalibrated.Fires on the first
advance()when the instance was constructed withcalibration=None. Supply an SBC-fittedCalibrationartifact via thecalibration=constructor parameter to correct interval coverage and silence the warning.
- class pytyche.experiment.sequential.SequentialExperiment(*, generator, schedule, treatments, cells=None, min_control_weight=0.05, min_explore_weight=0.05, max_segment_depth=3, min_segment_share=0.1, calibration=None, graduation_rule=None, seed=0, progress=False)[source]¶
Bases:
objectStateful round-by-round adaptive experiment loop.
The instance is its own iterator:
next(exp)(orexp.advance()) runs one round and returns the resultingExperimentsnapshot; iteration raisesStopIterationwhen the schedule is exhausted. Configuration is locked at construction; per-round cell overrides go throughadvance(cells=...).Scope: this surface assumes designed experiments — the operator emits the assignment rules (the plan’s cells and policies), the platform assigns per those rules, and per-visitor propensities are known and recorded. Heavily-confounded observational inference is out of scope for this API; for that setting, consider econml or DoubleML.
- Parameters:
generator (
Callable[[int,NextRoundPlan],tuple[ObservedExperimentData,CalibrationTruth|None]]) –generator(round_idx, plan)returning(observed, truth | None)— the single data-source contract. Sim-mode generators return ground truth; real-data generators returnNone(the mode may not flip between rounds). Every visitors frame must carry the reservedcellcolumn recording each visitor’s allocated cell id.schedule (
Schedule) – Per-round visitor counts (Scheduleprotocol).treatments (
Sequence[str]) – The full treatments universe, control first. Drops are recomputed from allocation history each round; dropped names never leave this universe.cells (
list[Cell] |None) – Optional round-0 cell-structure override replacing the cold-start Control/Explore 50/50 split.min_control_weight (
float) – Guaranteed Control-cell share on engine-proposed plans.min_explore_weight (
float) – Guaranteed Explore-cell share on engine-proposed plans.max_segment_depth (
int) – Policy-tree depth bound for the per-round analysis and recommendation.min_segment_share (
float) – Minimum per-leaf population share.calibration (
Calibration|None) – SBC-fitted artifact applied on-path each round, orNone(uncalibrated; warns once per instance).graduation_rule (
GraduationRule|None) –NoneusesExpectedLossRuleat its defaults.seed (
int) – Master seed — per-round fit seeds derive from it, and it seeds the policy tree’s stability bootstrap.progress (
bool) – When True, each round’s fit renders tqdm progress bars on stderr (passed through asfit_hurdle_bcf(progress=True)). Default False — silent.
- Raises:
ValueError – When
min_control_weight + min_explore_weightis not below 1.0 (no room for the Optimized cell).
- advance(cells=None)[source]¶
Run one round and return its
Experimentsnapshot.cellsoverrides this round’s cell structure only; subsequent rounds revert to the recommendation engine’s proposals. Overrides must satisfy the weight-sum invariant but are NOT subject to the engine’s min-weight floors.All state commits only after every step succeeds — a failure at any step (missing
cellcolumn, calibration regime mismatch, …) leaveshistoryand the cumulative data unchanged.- Raises:
StopIteration – When the schedule is exhausted.
ValueError – When the override cells’ weights do not sum to 1.0, when round data lacks the reserved
cellcolumn or labels visitors with ids outside the round’s plan, when a variant name falls outside the treatments universe, or when the round’s identity (experiment_id,metric, sim/real mode) conflicts with prior rounds.
- Parameters:
cells (
list[Cell] |None)- Return type:
- run_to_completion()[source]¶
Advance until the schedule is exhausted or a candidate emerges.
Returns
selffor chaining.- Raises:
ValueError – When the schedule is open-ended (
n_roundsisNone) — the operator must provide a stop condition.- Return type:
- property history: list[Experiment]¶
Completed rounds, oldest first (a defensive copy).
- property latest: Experiment | None¶
The most recent round, or
Nonebefore the first.
- property current_round_idx: int¶
Number of completed rounds (the next round’s index).
- property next_recommendation: NextRoundPlan | None¶
The engine’s plan for the next round;
Nonebefore round 0.
- graduation_candidates(sustained_rounds=2)[source]¶
Latest-round candidates sustained for at least sustained_rounds.
- Parameters:
sustained_rounds (
int)- Return type:
list[GraduationCandidate]
- has_graduation_candidate()[source]¶
Whether any candidate meets the default sustained-rounds bar.
- Return type:
bool
- has_credible_segments(stability_threshold=0.8)[source]¶
Whether any latest-round segment clears stability_threshold.
- Parameters:
stability_threshold (
float)- Return type:
bool
- dropped_treatments()[source]¶
Universe treatments absent from the latest plan’s active list.
- Return type:
list[str]
- property summary: str¶
Deterministic multi-paragraph prose over the series so far.
- property confidence: Literal['high', 'medium', 'low']¶
One-word label from the credibility + graduation state.
- pytyche.experiment.sequential.sequential_experiment(*, generator, schedule, treatments, cells=None, min_control_weight=0.05, min_explore_weight=0.05, max_segment_depth=3, min_segment_share=0.1, calibration=None, graduation_rule=None, seed=0, progress=False)[source]¶
Construct a
SequentialExperiment— the L1 entry point.The verb form of the
SequentialExperimentconstructor with the identical signature; see the class docstring for the parameter contract. Iterate the returned instance (next(exp)) to advance one round at a time, or callrun_to_completion()on a bounded schedule.Scope: this surface assumes designed experiments — the operator emits the assignment rules (the plan’s cells and policies), the platform assigns per those rules, and per-visitor propensities are known and recorded. Heavily-confounded observational inference is out of scope for this API; for that setting, consider econml or DoubleML.
- Parameters:
generator (
Callable[[int,NextRoundPlan],tuple[ObservedExperimentData,CalibrationTruth|None]])schedule (
Schedule)treatments (
Sequence[str])cells (
list[Cell] |None)min_control_weight (
float)min_explore_weight (
float)max_segment_depth (
int)min_segment_share (
float)calibration (
Calibration|None)graduation_rule (
GraduationRule|None)seed (
int)progress (
bool)
- Return type: