Skip to content

feat(empirical): Turnmark Equivalence, a shared-scale course map from 8.51M swims - #45

Open
Stanback wants to merge 1 commit into
mainfrom
feat/empirical-8.5m-triangulated
Open

Stanback wants to merge 1 commit into
mainfrom
feat/empirical-8.5m-triangulated

Conversation

@Stanback

@Stanback Stanback commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Summary

Replaces the pace-curve regression behind the turnmark-empirical-2026 method with Turnmark Equivalence, a model-based estimate of the equivalent time in another course. Each (event, category, course) gets a linear map in log time onto one SCY-anchored shared scale, fit from 8.51M swims (national-checkpoint-17). It estimates the equivalent time, not "what will this swimmer swim next"; that question is the separate predictor POC below.

Model (research/conversion-model/evaluate_and_train.py, receipt evaluation-checkpoint-08.json, method in REPORT.md)

  • Deming (errors-in-variables) lines per cell, with the noise ratio estimated from same-course repeat swims, weighted by swimmer.
  • Event lines shrink toward pool geometry and a flat multiplier; category cells shrink toward their event line.
  • Weighted least squares across the three course pairs gives one map per course, so A→B→A and A→B→C agree before rounding.
  • Evidence is counted over swimmers, not rows. The shift variance is swimmer-clustered and the slope variance is a disclosed approximation. Repeating a swimmer's rows changes nothing (tested).
  • No nonlinear stage. An earlier revision fitted one to flatten a pair-mean diagnostic that trends under unequal course noise even for the true map, so it was removed.
  • Validation was used to look for remaining curvature; test drove no choices.
  • data/empirical.json is schema 3: two-knot tables, lowEvidenceCells and preciseLatentRanges (14 KB).

Test split (39,314 rows, 4,710 held-out swimmers)

Method MAE
NCAA 3.041s
Flat multiplier 2.858s
Percentile, same input 2.788s
Equivalence 2.771s
  • Main evidence: −0.270s vs NCAA (CI −0.302 to −0.240) and −0.087s vs the fitted flat multiplier.
  • Against percentile maps: not distinguishable after Holm correction.
  • Errors by ability: a separate swim at least 31 days from both pair swims is a less-coupled diagnostic, not an unbiased one. On it, NCAA’s fastest-minus-slowest spread is −2.8% and this map’s −0.86%. A mid-range bend remains, which is a lead for a known-truth experiment, not a fix to ship.
  • Arithmetic: round trips are within 0.02s and there are no monotonicity violations.
  • Known limits:
    • Same-course repeats can't measure swimmer-specific course aptitude, so the noise ratio is an estimate.
    • The slow tail converts fast on the later-season and regional holdouts.
    • 1650/1500 is the one event NCAA wins.
    • Out-of-range times extrapolate.

Engine and clients

  • turnmark-core adds knot-map conversion and the EmpiricalOutOfRange and EmpiricalLowEvidence caveats; out-of-range wins when both apply. Elevation is computed in whole hundredths. The parity fixture has 1,008 cases.
  • Web, iOS, Android, SDK and MCP:
    • label the method "Turnmark Equivalence" and describe its result as an estimate;
    • show both caveats ("Outside the model’s fitted range: this estimate extrapolates beyond the available fit.").
  • The MCP resource is now r7.
  • canonical_event_key no longer buckets SCY 400 free or 800/1500 yd free with the 500/400 m events.

Also in this PR

  • Review fixes to engine arithmetic and evaluation design.
  • Canadian directory: clubs, facilities and university swim programs, with no contact data.
  • research/conversion-model/predictor/: a forward-only "likely time" predictor POC, not shipped.
    • Features require age recorded at the source swim, and a test checks that target-only fields can't change them.
    • 3.32s MAE vs 4.97s for NCAA.
    • Its tests aren't in CI.
  • Widget Wasm test: now asserts the standards payload is absent rather than a size ratio.
  • MCP spectrum labels stay inside the track at large text.

Test plan

  • Python research tests (101: known-truth recovery under unequal noise, duplication invariance) and predictor tests (16)
  • Independent reviewers reproduced the full evaluator run exactly and audited every report number against the receipt
  • cargo fmt, clippy, workspace tests
  • npm test (187), check, engine, mcp, sdk:package, Playwright (55), production Playwright (22), CI-change tests (84)
  • iOS app suite locally (28/28)
  • Android instrumented tests: the history tests fail in CI (under investigation); not runnable locally
  • iOS benchmark UI tests fail in CI; they were already failing on this PR before this revision

🤖 Generated with Claude Code

@Stanback Stanback changed the title Expand empirical conversion corpus to 8.51M swims with NCAA-free 168-cell triangulation feat: expand empirical conversion corpus to 8.51M swims with NCAA-free 168-cell Huber spline Oct 23, 2026
@Stanback
Stanback force-pushed the feat/empirical-8.5m-triangulated branch from c16752d to 3c6f95a Compare October 23, 2026 18:31
@Stanback Stanback changed the title feat: expand empirical conversion corpus to 8.51M swims with NCAA-free 168-cell Huber spline feat(empirical): expand conversion model to 8.51M swims with NCAA-free 168-cell Huber spline Oct 23, 2026
@Stanback
Stanback force-pushed the feat/empirical-8.5m-triangulated branch from 3c6f95a to b229939 Compare October 24, 2026 02:49
@Stanback Stanback changed the title feat(empirical): expand conversion model to 8.51M swims with NCAA-free 168-cell Huber spline feat(empirical): Turnmark Equivalence, a monotone shared-latent course map from 8.51M swims Oct 24, 2026
@Stanback
Stanback force-pushed the feat/empirical-8.5m-triangulated branch 3 times, most recently from c163d07 to 3c55c23 Compare October 24, 2026 03:14
@Stanback Stanback changed the title feat(empirical): Turnmark Equivalence, a monotone shared-latent course map from 8.51M swims feat(empirical): Turnmark Equivalence, a shared-scale course map from 8.51M swims Oct 24, 2026
@Stanback
Stanback force-pushed the feat/empirical-8.5m-triangulated branch 8 times, most recently from 3d99ada to c7a7f57 Compare October 24, 2026 06:42
… 8.51M swims

Replace the pace-curve regression behind turnmark-empirical-2026 with a
model-based equivalence estimate: per (event, category, course) a linear
map in log time onto one SCY-anchored scale, from Deming lines with a
swimmer-weighted repeat-swim noise ratio, empirical-Bayes shrinkage toward
pool geometry and a WLS reconciliation across course pairs. Evidence and
uncertainty count swimmers, not rows. data/empirical.json moves to
schema 3 (two-knot tables, low-evidence cells, precise ranges), and the
engine adds out-of-range and low-evidence caveats. Test MAE 2.771s vs
3.041s NCAA; a less-coupled separate-swim diagnostic is reported, and
validation only, not test, informs any curvature follow-up.

Also: review fixes to engine arithmetic and evaluation design, the event-
key fix for yard freestyle distances, the Canadian club/facility/university
directory, and a forward-only likely-time predictor POC (research only;
features require source-date age).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Stanback
Stanback force-pushed the feat/empirical-8.5m-triangulated branch from c7a7f57 to 09b0d0b Compare October 24, 2026 07:41

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant