Keep sequential confidence intervals finite and warn on negative variance estimates#97
Merged
jirisamek merged 1 commit intoJun 17, 2026
Conversation
…ance estimates The O'Brien-Fleming alpha spending function rounds the adjusted confidence level to 4 decimal places which produces exactly 1.0 early in the experiment. The t-quantile of confidence level 1.0 is infinite, making all confidence intervals inf or NaN. The adjusted confidence level is now capped at 0.9999 so confidence intervals stay finite (and appropriately wide) from day one. Metrics evaluated from pre-aggregated goals can produce negative variance estimates when sum_sqr_value is not a sum of squared per-unit goal totals, e.g. when a dimensional goal sums multiple dimension values per unit but squares were computed per dimension value. This produced silent NaN standard deviations, p-values and confidence intervals. The evaluation now emits an explicit warning naming the affected metrics and the likely cause. Also adds a regression test pinning that evaluate_by_unit computes sum_sqr_value from per-unit totals when a unit is split into multiple rows. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jirisamek
approved these changes
Jun 17, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Two related issues that surface as NaN/inf confidence intervals and NaN p-values when evaluating experiments:
Infinite confidence intervals early in a sequential test.
Statistics.obf_alpha_spending_functionrounds the adjusted confidence level to 4 decimal places. Early in an experiment the O'Brien-Fleming adjustment produces values like 0.9999984 which round to exactly 1.0. The t-quantile of confidence level 1.0 is infinite, so every confidence interval evaluates to inf or NaN (rel_se * inf), accompanied by a crypticRuntimeWarning: invalid value encountered in multiplyfromttest_evaluation. For example, on day 3 of an 18-day test the adjusted alpha is ~1.6e-6, which rounds to a confidence level of exactly 1.0.Silent NaN results on inconsistent pre-aggregated data.
evaluate_aggrequiressum_sqr_valueto be a sum of squared per-unit goal totals. When a metric matches multiple pre-aggregated rows per unit — typically a dimensional goal summed across several dimension values per unit, with squares computed per dimension value — the variance estimate(sum_sqr_value - sum_value^2/count) / (count - 1)goes negative, and std, p-value and confidence interval all turn NaN with no explanation. This cost us a lengthy investigation in production; the failure mode deserves a loud, named warning.Changes
MAX_SEQUENTIAL_CONFIDENCE_LEVEL = 0.9999. Confidence intervals early in a test are now finite and appropriately wide instead of infinite. Test expectations and thetest-sequential-v1golden data updated accordingly.UserWarningfrom metric evaluation when any metric has a negative variance estimate, naming the affected metrics, the likely cause and the remedies (pre-aggregatesum_sqr_valuefrom per-unit totals or useevaluate_by_unit).evaluate_by_unitcomputessum_sqr_valuefrom per-unit totals when a unit's goal is split into multiple input rows (the pivot inevaluate_by_unitcollapses them before squaring — this behavior is correct today and now guarded).Testing
make checkpasses: ruff clean, all 152 tests pass including the new ones (test_obf_alpha_spending_function_keeps_confidence_intervals_finite,test_agg_warns_on_negative_variance,test_by_unit_sums_unit_rows_before_squaring).🤖 Generated with Claude Code