Correlated races via latent Gaussian factors (and softmax races) - #14
Merged
Conversation
New module thurstone.correlated: - FactorRace: X_i = mu_i + v_i.f + e_i with f ~ N(0, I_k) and arbitrary idiosyncratic base densities. Conditionally on the factors the competitors are independent, so the package's fast field-product/divide-out identity applies at every quadrature node (Gauss-Hermite for small k, scrambled-Sobol QMC via optional scipy beyond). Deterministic and smooth in the abilities. - state_prices(keep=...) for scratch subsets; deletion_ensemble() gives P(j wins | i scratched) for all pairs from one conditional field pass. - solve_abilities: inverse calibration under correlation (damped fixed point; step set by the smallest effective pairwise noise from the TOTAL correlation including idiosyncratic variance). - factor_model: iterated principal-factor analysis (naive eigen-truncation invents off-diagonal correlation and is avoided deliberately). - Density.gumbel_min: independent min-wins races reproduce Luce/softmax exactly, so FactorRace with a Gumbel base is a correlated softmax race with an exact Luce limit; zero loadings recover Race.state_prices. Validated against Monte Carlo in tests (known-factor, equicorrelated-exact, softmax limit, scratch-ensemble consistency, calibration roundtrip). Origin and physics validation: kinetics.microprediction.org (experiments 3 and 6). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
- shared-base == per-competitor-list equivalence; ability translation invariance; monotonicity (stronger ability wins more); positivity and normalization across random fields; single-factor two-runner symmetry - error paths: mismatched loadings rows, base counts, lattices; nonpositive calibration targets - factor_model: exact diagonal, equicorrelated k=1 exactness - gaussian_nodes determinism; gumbel_min normalization and left skew - correlated-softmax IIA violation has the right sign after calibration (scratched runner's environment-sharer gains more than Luce renormalization) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
What
New module
thurstone.correlatedbringing the correlated-race technology developed and validated at kinetics.microprediction.org (experiments 3 and 6) into the base package, generalized to arbitrary base densities.FactorRace:X_i = mu_i + v_i·f + e_iwithf ~ N(0, I_k)latent Gaussian factors and any idiosyncratic baseDensityper competitor. Conditionally on the factors the competitors are independent, so the package's fast field-product/divide-out identity applies at every quadrature node. Deterministic and smooth in abilities.deletion_ensemble(): P(j wins | i scratched) for all pairs from one conditional field pass;state_prices(keep=...)for arbitrary scratch subsets.solve_abilities: inverse calibration under correlation (damped fixed point; step set by smallest effective pairwise noise from the total correlation).factor_model: iterated principal-factor analysis (naive eigen-truncation invents off-diagonal correlation and is deliberately avoided).Density.gumbel_min: independent min-wins races reproduce Luce/softmax exactly, so a Gumbel base + factors = correlated softmax race with an exact Luce limit. Zero loadings recoverRace.state_prices.Validation
12 tests, all Monte-Carlo-verified where applicable: known-factor model, equicorrelated k=1 exactness, softmax limit, non-IIA departure under correlation, scratch-ensemble vs per-scratch recompute (1e-10), calibration roundtrip, and the calibrate-then-scratch neighbor-inheritance effect (with the equal-ability uniform-redistribution counterexample documented — scratching is a marginal).
Core stays numpy-only; scipy is a soft dependency (Sobol nodes for k > 4, seeded-MC fallback).
🤖 Generated with Claude Code