Segment analysis and rollout
segment_heterogeneity
Section titled “segment_heterogeneity”segment_heterogeneity(estimates, alpha, tau_prior_scale)Cochran’s Q, tau^2, I^2, an HKSJ pooled effect, and tau-marginalised
per-segment shrinkage, over every declared segment for each (metric, method, group_id, dimension, source, estimand, value_scale) grouping
key in estimates.
estimates must come from a SINGLE run_breakout call - a
standalone call stamps source=None, so two independent calls on
the same dimension would silently merge into one Q.
A key needs at least 2 live segments on a scale to run a test;
absolute encouragement rows use their persisted additive moments for
the absolute scale, while rows without usable moments are dropped from
that scale only. A segment unusable on ONE scale only is dropped from
that scale’s math (excluded="zero_variance") and tested normally on
the other. A degenerate HKSJ pooled variance falls back to the wider
plug-in interval for that row only.
Only when posterior integration cannot be resolved within the numerical
budget are that scale’s shrunken rows withheld
(excluded="estimation_failed", with a
breakout.heterogeneity.posterior_integration_unresolved warning
carrying the failure’s context); the raw rows are unaffected.
The relative-scale raw row reuses BreakoutEstimate.lift
verbatim when no rebuild is needed; Q/tau^2/pooled/shrunken use the
raw pre-update lift.log_mean/lift.log_se (see
:func:_relative_raw_lift). A row whose stored interval was set by
a BH/FCR family-selection correction is withheld instead of rebuilt
(excluded="reference_not_normal", lift=None) only when the
requested alpha differs from that row’s own corrected alpha —
rebuilding it at a different, uncorrected alpha would silently
re-narrow or widen it back to nominal coverage. A matching-alpha
family-corrected row needs no such withhold and reuses its stored
interval verbatim instead.
Absolute-primary raw rows likewise preserve their stored intervals at a matching alpha. Allowed rebuilds use the primary sampling reference, not a relative row’s additive-sidecar reference.
Parameters
Section titled “Parameters”estimates : BreakoutEstimates
A single run_breakout call’s dense output.
alpha : float
Two-sided significance level, shared by every interval.
tau_prior_scale : float
HalfNormal prior scale on tau for the tau-marginalised shrinkage,
forwarded to :func:~increment.estimation.meta. marginalized_segment_intervals. The default (0.30) is calibrated
for the log-RR (relative) scale; an absolute-scale metric whose
true between-segment tau is not of that order (e.g. a dollar
metric) over-shrinks under the default with no warning — pass a
scale matching that metric’s own units.
Raises
Section titled “estimates : BreakoutEstimates
A single run_breakout call’s dense output.
alpha : float
Two-sided significance level, shared by every interval.
tau_prior_scale : float
HalfNormal prior scale on tau for the tau-marginalised shrinkage,
forwarded to :func:~increment.estimation.meta. marginalized_segment_intervals. The default (0.30) is calibrated
for the log-RR (relative) scale; an absolute-scale metric whose
true between-segment tau is not of that order (e.g. a dollar
metric) over-shrinks under the default with no warning — pass a
scale matching that metric’s own units.
Raises”ValueError
Propagated from cochran_q/hksj_pooled_mean on malformed
moment inputs; also raised when a live row’s stored relative-scale
interval must be rebuilt at alpha but the rebuild would
misrepresent it (wrong shape or reference distribution — see
:func:_relative_raw_lift). A row corrected by a BH/FCR
family-selection pass is withheld instead of raising when its
own corrected alpha differs from the requested one (see above).
Returns
Section titled “ValueError
Propagated from cochran_q/hksj_pooled_mean on malformed
moment inputs; also raised when a live row’s stored relative-scale
interval must be rebuilt at alpha but the rebuild would
misrepresent it (wrong shape or reference distribution — see
:func:_relative_raw_lift). A row corrected by a BH/FCR
family-selection pass is withheld instead of raising when its
own corrected alpha differs from the requested one (see above).
Returns”SegmentHeterogeneityResult
(summary, segments) - see :class:HeterogeneitySummary and
:class:SegmentEstimate.
segment_contrast
Section titled “segment_contrast”segment_contrast(estimates, dimension_value_a, dimension_value_b, alpha)Contrast segment dimension_value_a’s lift against dimension_value_b’s.
estimates must already be scoped to ONE (metric, method,
group_id, dimension, source, estimand, value_scale) combination -
exactly two rows, one per label - or this raises rather than
guessing which pair to contrast.
Relative rows (value_scale="relative") return a value on the
same back-transformed scale as
:func:increment.power.core.segment_pairwise_required_sample_size’s
contrast: value = exp(delta) - 1 where
delta = log1p(r_A) - log1p(r_B). Absolute rows
(value_scale="absolute", e.g. an encouragement LATE) return the
plain additive difference value_A - value_B with no log
transform - log1p is undefined at or below an additive effect of
-1, which a valid absolute effect routinely is.
Segments partition a breakout’s rows with independent control arms
and CUPED thetas, so the contrast variance is the plain sum
var_a + var_b.
Running this on every one of a dimension’s pairs without correction
re-introduces the multiple-comparisons problem it exists to avoid
for one pre-specified pair; use :func:increment.estimation.meta. cochran_q’s joint test when scanning every pair.
Raises
Section titled “Raises”ValueError
Not exactly one row per label, the two rows come from different
groupings, either is missing an interval, or either carries a
reference this rebuild cannot invert: non-fixed-horizon inference
(a sequential width is not a critical value times a standard error) or
a t sampling reference (built with a t critical value, not a Normal
one). Exact-binomial rows are also refused because their confidence
sets do not encode a Normal variance; rerun the breakout with a
fixed-horizon Normal-reference method, such as CUPED with valid
covariate moments, before contrasting those segments. A directional
(open) row IS accepted: its single calibrated bound recovers the
variance at the row’s own full allocated tail (Estimate.open_side);
an unavailable row (both bounds None) is not.
Every value below is unweighted: each usable segment contributes equally, regardless of the exposure it carries. An exposure-weighted policy value was measured before this shipped and deliberately left out — under weighting the winner’s-curse correction could not meet the accuracy bar the unweighted correction is adopted against, and a weighted headline whose selection bias cannot be removed honestly is worse than none.
segment_rollout_recommendation
Section titled “segment_rollout_recommendation”segment_rollout_recommendation(estimates, metrics, rollout_cost, tau_prior_scale)Recommend which segments to roll out, and price the rollout, for
each (metric, method, group_id, dimension, source, estimand, value_scale) grouping key found in estimates.
estimates must come from a SINGLE run_breakout call - a
standalone call stamps source=None, so independent calls on one
dimension would silently merge into a single selection problem.
Cost resolution, highest precedence first: an explicit
rollout_cost argument (a mapping’s unknown name is REFUSED); then
the metric’s own declared rollout_cost; then 0.0.
Only RELATIVE moments are read; see the module docstring. A key
needs at least 2 usable segments; fewer are silently skipped — so an
encouragement breakout’s LATE rows (additive lift, no log-scale
moments) form their own key and emit nothing, rather than counting
against the ITT key’s exclusions. A segment with unusable statistics
is dropped, reported excluded="zero_variance", selected=None.
Values are UNWEIGHTED by exposure - read :class:RolloutRecommendation
before quoting one.
Parameters
Section titled “Only RELATIVE moments are read; see the module docstring. A key
needs at least 2 usable segments; fewer are silently skipped — so an
encouragement breakout’s LATE rows (additive lift, no log-scale
moments) form their own key and emit nothing, rather than counting
against the ITT key’s exclusions. A segment with unusable statistics
is dropped, reported excluded="zero_variance", selected=None.
Values are UNWEIGHTED by exposure - read :class:RolloutRecommendation
before quoting one.
Parameters”estimates : BreakoutEstimates
A single run_breakout call’s dense output.
metrics : Sequence[Metric], optional
Metric declarations, read only for rollout_cost.
rollout_cost : float or Mapping[str, float], optional
Explicit break-even override(s), as relative lift.
tau_prior_scale : float
HalfNormal prior scale on tau, forwarded to
:func:~increment.estimation.rollout.segment_rollout.
Raises
Section titled “estimates : BreakoutEstimates
A single run_breakout call’s dense output.
metrics : Sequence[Metric], optional
Metric declarations, read only for rollout_cost.
rollout_cost : float or Mapping[str, float], optional
Explicit break-even override(s), as relative lift.
tau_prior_scale : float
HalfNormal prior scale on tau, forwarded to
:func:~increment.estimation.rollout.segment_rollout.
Raises”ValueError
An explicit rollout_cost key naming no known metric, a
non-finite / <= -1 cost, or the estimator’s own guards —
including estimation.meta.posterior_integration_unresolved,
propagated unchanged when a key’s tau posterior cannot be
integrated within the numerical budget: a recommendation row has
no field to carry that reason, and "refuse" means the offset
guard fired, so the failure is never reported as one.
Returns
Section titled “ValueError
An explicit rollout_cost key naming no known metric, a
non-finite / <= -1 cost, or the estimator’s own guards —
including estimation.meta.posterior_integration_unresolved,
propagated unchanged when a key’s tau posterior cannot be
integrated within the numerical budget: a recommendation row has
no field to carry that reason, and "refuse" means the offset
guard fired, so the failure is never reported as one.
Returns”SegmentRolloutResult
(recommendations, segments) - see
:class:RolloutRecommendation and :class:RolloutSegment.