Seven LightGBM heads, one pricing layer, and a decade of result sheets β a tour of every number the prediction app shows, what each one actually measures, and how they fit together. New since the Tour: a day-type retrieval channel that re-picks who's in the conversation without touching a single price.
#plain (friendly version), #tdf (Tour predictions), #books (model vs bookmakers), #heads (how the heads disagree).
Same field, seven opinions
Every head saw identical inputs on 3 July β the same 184 riders, the same form, the same course profiles. Whatever differs between their outputs is pure architecture: what each head was trained to predict, over which population, with which loss. The Tour runs give us seven parallel experiments, and for GC the devigged book acts as an outside referee.
"Effective contenders" = exp(entropy) of a win book: how many riders meaningfully share it. Top-3 % = probability mass on the three favorites.
| Scenario | Cascade top-3 % | Cascade eff. contenders | LR top-3 % | LR eff. contenders | Book top-3 % | Book eff. contenders |
|---|---|---|---|---|---|---|
| GC | 65 | 10.8 | 60 | 10.9 | 84 | 4.4 |
| Flat sprint | 78 | 7.8 | 67 | 10.8 | β | β |
| Reduced sprint | 68 | 10.6 | 57 | 14.8 | β | β |
| Punchy | 59 | 15.3 | 56 | 15.0 | β | β |
| Mountain | 58 | 16.9 | 55 | 14.8 | β | β |
| TT ~30 min | 62 | 13.4 | 59 | 12.0 | β | β |
| Queen stage | 57 | 17.4 | 52 | 17.7 | β | β |
The headline surprise: the two heads' famous disagreement mostly isn't about shape. Force the cascade's quotes into a coherent book (they sum to 1.65 on GC β it's a per-rider conditional head, not a book) and it spreads the race across ~11 effective contenders, almost exactly like LambdaRank. The bookmaker spreads it across 4.4. The cascade's per-rider quote on PogaΔar (62.7%) matches the book's 63.0% β but it achieves that while also quoting everyone else generously, which a coherent book can't do. So the deep systematic pattern is not "cascade sharp, LR flat"; it's both heads hedge harder than the market, and the cascade hides it in an inflated book.
GC win probability, grouped by the book's own odds bands (all books normalized over the same 40 priced riders).
| Odds band | Book % | Cascade % | LR % | Blend % |
|---|---|---|---|---|
| Favorites (odds < 10)2 riders | 78.6 | 53.5 | 47.1 | 48.9 |
| Contenders (10β50)4 riders | 13.0 | 32.1 | 36.2 | 35.0 |
| Longshots (51β200)4 riders | 3.7 | 3.2 | 6.6 | 5.6 |
| Extreme (> 200)30 riders | 4.7 | 11.2 | 10.1 | 10.4 |
Every head makes the same two transfers, in the same direction: out of the top two favorites (book 78.6%, ours ~47β54%) and into the 10β50 band and the extreme tail. The middle-band excess is mostly the information gap β Evenepoel and Lipowitz live there, and our heads don't know what the market knows. The tail excess (11% vs 4.7% on 200/1+ shots) is the models' trained caution: three-week races have delivered enough chaos in the training data that no head will zero out 30 riders the way a bookmaker will. Note how uniform the three columns are β this is a property of the stack, not of any one head.
The ten biggest cascade-vs-LambdaRank gaps on GC, with the book's verdict on each.
| Rider | Book % (devig) | Cascade % | LR % | Book sides with |
|---|---|---|---|---|
| Pogacar Tadejbook odds 1.3 | 63.0 | 39.6 | 34.5 | Cascade |
| del Toro Isaacbook odds 26 | 3.1 | 2.3 | 5.3 | Cascade |
| Ayuso Juanbook odds 51 | 1.6 | 2.0 | 3.8 | Cascade |
| Vingegaard Jonasbook odds 5.25 | 15.6 | 13.9 | 12.6 | Cascade |
| Lipowitz Florianbook odds 41 | 2.0 | 9.3 | 10.4 | Cascade |
| van der Poel Mathieubook odds 2001 | 0.0 | 1.1 | 0.2 | LambdaRank |
| Pidcock Tombook odds 151 | 0.5 | 0.4 | 1.1 | Cascade |
| Martinez Lennybook odds 201 | 0.4 | 1.2 | 0.6 | LambdaRank |
| Johannessen Tobias Hallandbook odds 81 | 1.0 | 0.3 | 0.8 | LambdaRank |
| McNulty Brandonbook odds 801 | 0.1 | 0.8 | 0.3 | LambdaRank |
Score it across the whole market and the split is clean: among favorites and contenders (odds β€ 50) the book sides with the cascade 5 times out of 6; among longshots it sides with LambdaRank 17 times out of 34. That is the two-head design thesis β sharp head for the top, calibrated head for the field β endorsed by an independent market. It's also exactly the split the pricing layer already encodes: the corrector fixes the cascade at the top, while the blend leans 80% on LambdaRank everywhere else.
Rank correlation (Spearman) between heads, per scenario. 1.00 = identical ordering.
| Scenario | Cascade ~ LR | Bucket ~ Stopwatch | Cascade ~ Elo |
|---|---|---|---|
| GC | 0.96 | 0.87 | 0.41 |
| Flat sprint | 0.92 | 0.30 | 0.42 |
| Reduced sprint | 0.91 | 0.23 | 0.56 |
| Punchy | 0.95 | 0.89 | 0.52 |
| Mountain | 0.95 | 0.96 | 0.40 |
| TT ~30 min | 0.92 | 0.94 | 0.37 |
| Queen stage | 0.95 | 0.95 | 0.42 |
Cascade and LambdaRank order the field near-identically everywhere (0.91β0.96) β their disagreement is magnitude, never ranking. The interesting column is the middle one: the bucket head and the time-gap head agree almost perfectly on mountain days and time trials (0.87β0.96) and decouple completely on sprint days (0.23β0.30). That's physics, not a bug: in a bunch sprint the entire peloton records the same finishing time, so "seconds behind the winner" stops encoding finishing order β the stopwatch goes blind exactly when the sorter still sees fine. It's the clearest demonstration in the data that the heads measure different physical quantities, which is why stacking them as features works. Elo, meanwhile, is the least redundant signal in the stack: rank agreement with the cascade of only 0.37β0.56, highest on the sprint-and-punchy profiles where finishes are literally contested duels (which is what Elo counts) and lowest on time trials, where nothing is. Low redundancy is exactly why it earned its place as a feature.
Every other head redistributes ~1.0 of win probability between riders. The DNF head's output moves with the scenario itself.
| Scenario | Mean DNF % | Max DNF % | Mountain score (input) |
|---|---|---|---|
| GC | 7.2 | 20.3 | 0.22 |
| Flat sprint | 0.4 | 0.7 | 0.00 |
| Reduced sprint | 0.4 | 0.9 | 0.01 |
| Punchy | 0.6 | 1.2 | 0.27 |
| Mountain | 0.6 | 1.3 | 0.53 |
| TT ~30 min | 0.2 | 0.8 | 0.00 |
| Queen stage | 0.5 | 1.1 | 0.51 |
Single stages barely register (0.2β0.6% mean β you rarely abandon on the day itself), the time trial is the safest of all, and the GC scenario jumps to 7.3% mean with individual riders above 20% β because finishing a three-week race is a genuinely different proposition than finishing a Tuesday. This is why DNF multiplication lives at the pricing layer: it's a per-scenario survival discount, orthogonal to the who-beats-whom question every other head answers.
Model vs market
Odds captured 3 July 2026 (the day before the Grand DΓ©part) from the Kambi feed that powers Unibet β the same numbers shown on the consumer site, taken in one API snapshot and archived. Bookmaker odds carry a margin (this win market sums to 22% over a fair book), so every "Book %" below is devigged: rescaled so the market's probabilities sum to what a fair book would.
Which of our heads to compare: the LambdaRank column is our calibrated book β that's the honest apples-to-apples line. The cascade is our winner-picker, sharp at the top but not book-normalized. One known artifact matters here: LambdaRank's per-race softmax refuses extreme favorites, so its PogaΔar number is a floor, not an opinion β at the very top of the market, the cascade is our real quote.
40 riders priced by the book, all matched to our board. Sorted by book odds.
| Rider | Book odds | Book % (devig) | Blend % | Cascade % | LR % | LR β book (pp) |
|---|---|---|---|---|---|---|
| Pogacar TadejUAE Team Emirates-XRG | 1.3 | 63.0 | 57.8 | 62.7 | 33.7 | -29.3 |
| Vingegaard JonasTeam Visma | Lease a Bike | 5.25 | 15.6 | 20.9 | 22.1 | 12.4 | -3.2 |
| Seixas PaulDecathlon CMA CGM Team | 15 | 5.5 | 10.2 | 10.4 | 6.1 | +0.7 |
| del Toro IsaacUAE Team Emirates-XRG | 26 | 3.1 | 7.2 | 3.7 | 5.2 | +2.0 |
| Evenepoel RemcoRed Bull-BORA-hansgrohe | 34 | 2.4 | 22.7 | 22.0 | 13.9 | +11.5 |
| Lipowitz FlorianRed Bull-BORA-hansgrohe | 41 | 2.0 | 16.2 | 14.7 | 10.1 | +8.1 |
| Ayuso JuanLidl-Trek | 51 | 1.6 | 5.3 | 3.1 | 3.7 | +2.1 |
| Johannessen Tobias HallandUno-X Mobility | 81 | 1.0 | 1.0 | 0.4 | 0.8 | -0.2 |
| Carapaz RichardEF Education-EasyPost | 151 | 0.5 | 1.2 | 0.9 | 0.8 | +0.2 |
| Pidcock TomPinarello-Q36.5 Pro Cycling Team | 151 | 0.5 | 1.5 | 0.7 | 1.1 | +0.6 |
| Tiberi AntonioBahrain Victorious | 201 | 0.4 | 0.2 | 0.1 | 0.1 | -0.3 |
| Martinez LennyBahrain Victorious | 201 | 0.4 | 1.3 | 1.9 | 0.6 | +0.2 |
| Skjelmose MattiasLidl-Trek | 201 | 0.4 | 1.7 | 1.2 | 1.2 | +0.8 |
| Uijtdebroeks CianMovistar Team | 251 | 0.3 | 0.5 | 0.5 | 0.3 | -0.0 |
| Arensman ThymenNetcompany INEOS | 251 | 0.3 | 1.0 | 0.9 | 0.7 | +0.3 |
| Gee DerekLidl-Trek | 301 | 0.3 | 0.7 | 0.7 | 0.5 | +0.2 |
The two systems shake hands at the very top.
Book devig on PogaΔar: 63.0%. Our cascade: 62.7%. Two completely different machines β a global betting market and a LightGBM stack trained on result sheets β land within a point of each other on the biggest question. Seixas is the same story in miniature: the book makes the 19-year-old third favorite (5.5%), and our heads have him 6β10%. Del Toro, Ayuso, Johannessen, Carapaz: all within ~1pp of the book. When we agree this closely, both systems are probably right, and there is no bet.
The giant gaps are information, not value.
Evenepoel: book 2.4%, our blend 22.7%. Lipowitz: book 2.0%, blend 16.2%. And in the "winner without PogaΔar" market the book gives Vingegaard 47.9% of the non-PogaΔar race where we give him 19%. Read together, the market is telling one coherent story β it believes only one rider genuinely challenges PogaΔar, and that Evenepoel and Lipowitz will not contest GC at full strength. One important self-correction on Vingegaard specifically: a backtest run after this snapshot found the model systematically underprices riders who finished a grand tour within ~45 days (they win GC at ~1.6Γ our quote) β Vingegaard won the Giro 33 days ago, so much of his gap is our measured bias, not the book's private information. Our database runs to 21 June but contains results, not news: no crash reports, no leadership announcements, no route knowledge β and Evenepoel has not raced since 26 April, a fact our model can only see as stale form while the market knows the reason. A 10Γ gap on a headline rider means the market knows a fact we don't β the move is to find the fact, not to bet against it.
Small, calibrated disagreements β not the screaming gaps.
The credible candidates are where our calibrated head sits modestly above the devigged book with no obvious news story: Ayuso +2.1pp and del Toro +2.0pp β notably the pair who just finished 3rd and 1st at the DauphinΓ©, a result the model has digested and this odds snapshot predates β plus Seixas (+0.7pp) and Pidcock fractionally. Structurally, the softer targets are the secondary markets β top-6 and top-10 carry ~41% margins (vs 22% on the win market), and place probabilities are exactly what our DNF-adjusted, calibrated stack does best. That's where a retail book is most likely to be lazy, and where our honest prices have teeth.
The book's conditional race (margin 44%, devigged) against our blend with PogaΔar removed and renormalized. This is the cleanest view of the disagreement about who the real challenger is.
| Rider | Book odds | Book % (devig) | Ours, renormed % | Ξ (pp) |
|---|---|---|---|---|
| Jonas Vingegaard | 1.45 | 47.9 | 19.4 | -28.4 |
| Paul Seixas | 5 | 13.9 | 9.5 | -4.4 |
| Remco Evenepoel | 9 | 7.7 | 21.1 | +13.4 |
| Isaac Del Toro | 12 | 5.8 | 6.6 | +0.9 |
| Florian Lipowitz | 13 | 5.3 | 15.0 | +9.7 |
| Juan Ayuso | 17 | 4.1 | 4.9 | +0.8 |
| Richard Carapaz | 21 | 3.3 | 1.1 | -2.2 |
| Tobias Halland Johannessen | 26 | 2.7 | 1.0 | -1.7 |
Stage 1 is a team time trial β a discipline our rider-level models don't price at all. The book also runs three-week jersey markets that need the full route and points structure. These boards are shown as book-implied probabilities (devigged); we have no counter-quote.
Stage 1 TTT β winning team (margin 21%)
| Outcome | Odds | % |
|---|---|---|
| Netcompany INEOS | 1.85 | 44.8 |
| UAE Team Emirates - XRG | 4.25 | 19.5 |
| Red Bull - BORA - hansgrohe | 6.5 | 12.7 |
| Team Visma | Lease a Bike | 7.5 | 11.0 |
| Lidl - Trek | 15 | 5.5 |
Yellow after stage 1
| Outcome | Odds | % |
|---|---|---|
| KΓ©vin Vauquelin | 2.25 | 28.7 |
| Tadej PogaΔar | 4.25 | 15.2 |
| Remco Evenepoel | 7 | 9.2 |
| Jonas Vingegaard | 9 | 7.2 |
| Thymen Arensman | 9 | 7.2 |
Points jersey
| Outcome | Odds | % |
|---|---|---|
| Jasper Philipsen | 2.1 | 31.4 |
| Mads Pedersen | 4.5 | 14.6 |
| Tim Merlier | 4.5 | 14.6 |
| Olav Kooij | 6 | 11.0 |
| Biniam Girmay | 7 | 9.4 |
Mountains jersey
| Outcome | Odds | % |
|---|---|---|
| Tadej PogaΔar | 2.1 | 30.6 |
| Lenny Martinez | 3.75 | 17.2 |
| Richard Carapaz | 5 | 12.9 |
| Jonas Vingegaard | 15 | 4.3 |
| Valentin Paret-Peintre | 17 | 3.8 |
Youth jersey
| Outcome | Odds | % |
|---|---|---|
| Paul Seixas | 2.25 | 35.0 |
| Isaac Del Toro | 2.75 | 28.7 |
| Juan Ayuso | 5 | 15.8 |
| Matthew Riccitello | 19 | 4.1 |
| Antonio Tiberi | 21 | 3.8 |
Teams classification
| Outcome | Odds | % |
|---|---|---|
| UAE Team Emirates - XRG | 1.7 | 46.8 |
| Red Bull - BORA - hansgrohe | 5 | 15.9 |
| Team Visma | Lease a Bike | 8 | 9.9 |
| Lidl - Trek | 9 | 8.8 |
| Netcompany INEOS | 11 | 7.2 |
Two structural blind spots of ours show up here. The book knows the actual 2026 route β which archetypes occur on which days, and that the race opens with a TTT feeding the yellow-jersey market. And the jersey markets price three-week arcs: the points jersey has Philipsen (2.1) ahead of Merlier (4.5) even though Merlier beats him on our single flat-day board β because the green jersey is won by surviving hills and hoovering intermediate sprints for three weeks, not by being fastest on one day.
The book prices each rider to win at least one of 21 stages; our number is the single best day we could find for them across the six archetypes. These are different bets β the gap between the columns is mostly the value of having 21 chances, breakaway luck, and route knowledge. Where the book's "yes" is rich and our best day is tiny (van der Poel, Pedersen, Healy, Carapaz), the book is pricing opportunism our stage boards structurally under-count.
| Rider | Book "yes" | Implied % | Our best day % | Best archetype |
|---|---|---|---|---|
| Tadej PogaΔar | 1.09 | 91.7 | 45.8 | Individual time trial (~30 min) |
| Tim Merlier | 1.33 | 75.2 | 42.9 | Flat stage, big bunch sprint |
| Remco Evenepoel | 1.45 | 69.0 | 18.9 | Individual time trial (~30 min) |
| Mathieu van der Poel | 1.6 | 62.5 | 3.3 | Reduced-group hilly sprint |
| Mads Pedersen | 1.6 | 62.5 | 2.4 | Reduced-group hilly sprint |
| Richard Carapaz | 1.65 | 60.6 | 1.6 | Mountain stage, summit finish |
| Olav Kooij | 1.65 | 60.6 | 35.8 | Flat stage, big bunch sprint |
| Jasper Philipsen | 1.65 | 60.6 | 21.0 | Flat stage, big bunch sprint |
| Lenny Martinez | 1.7 | 58.8 | 2.1 | Mountain stage, summit finish |
| Ben Healy | 2 | 50.0 | 0.5 | Queen stage, long, brutal mountains |
| Tom Pidcock | 2 | 50.0 | 1.5 | Punchy hilly stage |
| Romain GrΓ©goire | 2.1 | 47.6 | 0.8 | Punchy hilly stage |
| Isaac Del Toro | 2.25 | 44.4 | 7.6 | Punchy hilly stage |
| Jonas Vingegaard | 2.5 | 40.0 | 12.2 | Mountain stage, summit finish |
This snapshot is archived (raw API payloads + parsed markets + margin diagnostics) as the first entry of a going-forward odds archive, alongside our own logged predictions. After Paris, the two get settled against results β per-market log loss for us and for the devigged book, the same yardstick our experiment gate uses. That, repeated over races, is the only honest answer to "can this model beat the books" β one Tour is a single sample. Until then: the model's job this month is to be well-calibrated; the market's job is to know things. The interesting work lives in the gap.
Tour de France 2026
These are live predictions from the production stack, generated on 3 July 2026 from the official startlist (184 riders, 23 teams; 184 matched to the database). One general-classification forecast, plus the same field run through six stage archetypes β hypothetical stage profiles built by averaging real Tour stages from 2021β2025 that the model itself scores as that type of day.
Read it honestly: archetypes are course profiles, not the actual 2026 route β think "if Wednesday is a pure bunch-sprint day, here's the board." The database is current through 21 June 2026 β Giro, Tour de Suisse, and (after a same-day backfill) the full rebranded DauphinΓ© are all in; these boards were regenerated on 3 July with that complete picture. β marks the model's top-15 contender gate. Model estimates, not betting advice.
Final overall standings after three weeks. References: the last five Tour GC outcomes (2021β2025), so the model prices the yellow jersey the way those editions actually resolved.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | Elo | |
|---|---|---|---|---|---|---|---|---|---|
| 1 | β Pogacar TadejUAE Team Emirates-XRG | 57.8 | 62.7 | 33.7 | 85.8 | 89.3 | 6.8 | 63.1 | 1,874 |
| 3 | β Evenepoel RemcoRed Bull-BORA-hansgrohe | 22.7 | 22.0 | 13.9 | 52.3 | 64.7 | 7.7 | 21.9 | 1,704 |
| 2 | β Vingegaard JonasTeam Visma | Lease a Bike | 20.9 | 22.1 | 12.4 | 58.6 | 69.7 | 7.9 | 21.9 | 1,751 |
| 4 | β Lipowitz FlorianRed Bull-BORA-hansgrohe | 16.2 | 14.7 | 10.1 | 48.9 | 63.1 | 5.7 | 15.0 | 1,624 |
| 5 | β Seixas PaulDecathlon CMA CGM Team | 10.2 | 10.4 | 6.1 | 23.1 | 36.1 | 13.1 | 9.8 | 1,602 |
| 6 | β del Toro IsaacUAE Team Emirates-XRG | 7.2 | 3.7 | 5.2 | 15.5 | 29.1 | 7.5 | 3.7 | 1,665 |
| 7 | β Ayuso JuanLidl-Trek | 5.3 | 3.1 | 3.7 | 14.5 | 22.8 | 8.6 | 3.1 | 1,638 |
| 13 | β Skjelmose MattiasLidl-Trek | 1.7 | 1.2 | 1.2 | 3.7 | 6.5 | 8.9 | 1.2 | 1,661 |
| 22 | Pidcock TomPinarello-Q36.5 Pro Cycling Team | 1.5 | 0.7 | 1.1 | 12.0 | 19.5 | 7.2 | 0.7 | 1,623 |
| 17 | Vauquelin KΓ©vinNetcompany INEOS | 1.4 | 1.3 | 0.9 | 4.9 | 12.2 | 6.0 | 1.3 | 1,628 |
| 12 | β Jorgenson MatteoTeam Visma | Lease a Bike | 1.3 | 0.8 | 0.9 | 3.6 | 7.7 | 6.5 | 0.9 | 1,621 |
| 19 | Martinez LennyBahrain Victorious | 1.3 | 1.9 | 0.6 | 10.1 | 35.4 | 5.9 | 2.0 | 1,606 |
| 8 | β Carapaz RichardEF Education-EasyPost | 1.2 | 0.9 | 0.8 | 4.4 | 11.3 | 7.0 | 0.9 | 1,662 |
| 16 | β Yates AdamUAE Team Emirates-XRG | 1.2 | 0.9 | 0.8 | 3.5 | 8.2 | 7.3 | 0.9 | 1,602 |
| 18 | Johannessen Tobias HallandUno-X Mobility | 1.0 | 0.4 | 0.8 | 11.9 | 27.1 | 6.0 | 0.4 | 1,588 |
Pan-flat run-in, full bunch gallop. Built from stages the model itself scores as pure sprint (score 1.0): Cavendish, Philipsen and Merlier wins.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | |
|---|---|---|---|---|---|---|---|---|
| 5 | β Merlier TimSoudal Quick-Step | 42.9 | 51.9 | 27.7 | 71.6 | 80.1 | 0.4 | 51.9 |
| 4 | β Kooij OlavDecathlon CMA CGM Team | 35.8 | 42.5 | 23.4 | 64.9 | 72.9 | 0.4 | 42.5 |
| 1 | β Philipsen JasperAlpecin-Premier Tech | 21.0 | 17.3 | 15.6 | 45.2 | 58.0 | 0.4 | 17.3 |
| 16 | β Gaviria FernandoCaja Rural-Seguros RGA | 4.8 | 1.2 | 4.2 | 8.6 | 17.3 | 0.5 | 1.2 |
| 10 | β De Lie ArnaudLotto-IntermarchΓ© | 4.3 | 1.7 | 3.7 | 11.9 | 25.6 | 0.4 | 1.7 |
| 2 | β Kanter MaxXDS Astana Team | 4.0 | 2.7 | 3.1 | 15.4 | 30.7 | 0.4 | 2.7 |
| 7 | β Girmay BiniamNSN Cycling Team | 3.7 | 2.4 | 2.9 | 13.3 | 24.2 | 0.4 | 2.4 |
| 18 | β de Kleijn ArvidTudor Pro Cycling Team | 3.6 | 2.0 | 2.9 | 9.5 | 20.2 | 0.6 | 2.0 |
| 15 | β Ackermann PascalTeam Jayco-AlUla | 2.7 | 1.3 | 2.2 | 8.1 | 16.8 | 0.6 | 1.3 |
| 12 | β WΓ¦renskjold SΓΈrenUno-X Mobility | 2.0 | 2.0 | 1.4 | 8.3 | 16.5 | 0.4 | 2.0 |
Enough lumps to drop half the fast men β a sprint, but from a thinned group of durable sprinters and classics riders.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | |
|---|---|---|---|---|---|---|---|---|
| 3 | β Kooij OlavDecathlon CMA CGM Team | 34.4 | 37.2 | 23.2 | 59.8 | 67.0 | 0.4 | 37.2 |
| 2 | β Merlier TimSoudal Quick-Step | 31.0 | 44.2 | 18.2 | 63.4 | 72.5 | 0.4 | 44.2 |
| 1 | β Philipsen JasperAlpecin-Premier Tech | 21.0 | 16.4 | 15.7 | 40.8 | 52.4 | 0.4 | 16.4 |
| 8 | β Girmay BiniamNSN Cycling Team | 7.8 | 3.8 | 6.4 | 21.8 | 32.5 | 0.4 | 3.8 |
| 7 | β De Lie ArnaudLotto-IntermarchΓ© | 7.2 | 2.4 | 6.2 | 14.9 | 30.5 | 0.4 | 2.4 |
| 5 | β Kanter MaxXDS Astana Team | 4.6 | 2.9 | 3.6 | 15.7 | 31.1 | 0.4 | 2.9 |
| 25 | β Gaviria FernandoCaja Rural-Seguros RGA | 3.9 | 1.0 | 3.4 | 7.6 | 14.8 | 0.5 | 1.0 |
| 6 | β Pogacar TadejUAE Team Emirates-XRG | 3.8 | 10.5 | 1.0 | 14.3 | 17.1 | 0.4 | 10.5 |
| 4 | β van der Poel MathieuAlpecin-Premier Tech | 3.3 | 3.1 | 2.4 | 11.7 | 18.6 | 0.5 | 3.1 |
| 10 | β WΓ¦renskjold SΓΈrenUno-X Mobility | 2.5 | 2.7 | 1.7 | 10.6 | 19.2 | 0.5 | 2.7 |
Short steep finish or spiky final hour β Mur-de-Bretagne, Bologna, Rouen. In the model's inputs these read as rolling stages with moderate mountain score; the puncheur signal comes from rider-course fit, not the course score alone.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | |
|---|---|---|---|---|---|---|---|---|
| 1 | β Pogacar TadejUAE Team Emirates-XRG | 42.9 | 47.1 | 36.0 | 75.8 | 80.7 | 0.5 | 47.1 |
| 4 | β Seixas PaulDecathlon CMA CGM Team | 11.5 | 9.6 | 10.4 | 17.6 | 26.3 | 1.2 | 9.5 |
| 2 | β Evenepoel RemcoRed Bull-BORA-hansgrohe | 11.4 | 12.3 | 9.7 | 30.9 | 38.7 | 0.7 | 12.3 |
| 5 | β del Toro IsaacUAE Team Emirates-XRG | 7.6 | 4.8 | 7.3 | 12.3 | 22.6 | 0.6 | 4.8 |
| 3 | β Vingegaard JonasTeam Visma | Lease a Bike | 6.5 | 7.3 | 5.4 | 22.1 | 30.5 | 0.6 | 7.3 |
| 7 | β Lipowitz FlorianRed Bull-BORA-hansgrohe | 4.4 | 2.6 | 4.3 | 10.3 | 15.8 | 0.5 | 2.6 |
| 6 | β Ayuso JuanLidl-Trek | 3.0 | 1.7 | 2.9 | 8.4 | 12.2 | 0.8 | 1.7 |
| 11 | β Pidcock TomPinarello-Q36.5 Pro Cycling Team | 1.5 | 0.8 | 1.5 | 4.4 | 9.5 | 0.7 | 0.8 |
| 10 | β Yates AdamUAE Team Emirates-XRG | 1.3 | 0.9 | 1.2 | 3.9 | 8.1 | 0.6 | 0.9 |
| 12 | β Martinez LennyBahrain Victorious | 1.2 | 0.9 | 1.2 | 3.9 | 7.5 | 0.5 | 0.9 |
A real summit finish (Luz Ardiden, Cauterets, Pla d'Adet, Hautacam-style) at standard length. GC riders decide it.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | |
|---|---|---|---|---|---|---|---|---|
| 1 | β Pogacar TadejUAE Team Emirates-XRG | 44.1 | 47.1 | 34.1 | 76.1 | 81.5 | 0.5 | 47.2 |
| 3 | β Evenepoel RemcoRed Bull-BORA-hansgrohe | 14.5 | 14.3 | 11.5 | 38.2 | 48.9 | 0.7 | 14.3 |
| 2 | β Vingegaard JonasTeam Visma | Lease a Bike | 12.2 | 11.6 | 9.8 | 39.0 | 49.6 | 0.7 | 11.6 |
| 5 | β Seixas PaulDecathlon CMA CGM Team | 9.1 | 8.2 | 7.4 | 15.0 | 25.0 | 1.3 | 8.1 |
| 4 | β del Toro IsaacUAE Team Emirates-XRG | 6.2 | 3.8 | 5.5 | 12.1 | 24.5 | 0.6 | 3.8 |
| 6 | β Lipowitz FlorianRed Bull-BORA-hansgrohe | 6.2 | 4.1 | 5.4 | 16.5 | 28.2 | 0.5 | 4.1 |
| 7 | β Ayuso JuanLidl-Trek | 2.4 | 1.9 | 2.0 | 7.7 | 12.0 | 0.8 | 1.9 |
| 8 | β Martinez LennyBahrain Victorious | 2.1 | 2.2 | 1.6 | 6.5 | 12.2 | 0.5 | 2.2 |
| 9 | β Carapaz RichardEF Education-EasyPost | 1.6 | 1.3 | 1.3 | 5.5 | 11.0 | 0.6 | 1.3 |
| 13 | β Johannessen Tobias HallandUno-X Mobility | 1.5 | 0.8 | 1.4 | 4.2 | 11.0 | 0.5 | 0.8 |
A ~30-minute individual race against the clock, from the Tour's recent mid-length TTs.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | |
|---|---|---|---|---|---|---|---|---|
| 1 | β Pogacar TadejUAE Team Emirates-XRG | 45.8 | 47.8 | 36.8 | 82.0 | 85.7 | 0.5 | 47.7 |
| 2 | β Evenepoel RemcoRed Bull-BORA-hansgrohe | 18.9 | 20.5 | 15.0 | 49.1 | 57.0 | 0.5 | 20.5 |
| 3 | β Tarling JoshuaNetcompany INEOS | 8.4 | 8.0 | 7.0 | 23.4 | 32.1 | 0.3 | 8.0 |
| 5 | β Lipowitz FlorianRed Bull-BORA-hansgrohe | 7.1 | 3.4 | 6.7 | 15.9 | 25.6 | 0.2 | 3.4 |
| 6 | β Seixas PaulDecathlon CMA CGM Team | 7.1 | 5.4 | 6.2 | 11.9 | 20.9 | 0.8 | 5.4 |
| 4 | β Vingegaard JonasTeam Visma | Lease a Bike | 5.3 | 4.6 | 4.5 | 17.0 | 26.0 | 0.5 | 4.6 |
| 8 | β Ayuso JuanLidl-Trek | 3.4 | 2.0 | 3.2 | 8.0 | 12.5 | 0.6 | 1.9 |
| 7 | β Ganna FilippoNetcompany INEOS | 2.7 | 2.5 | 2.2 | 13.5 | 22.5 | 0.2 | 2.5 |
| 10 | β Foss TobiasNetcompany INEOS | 2.2 | 1.0 | 2.1 | 4.5 | 9.8 | 0.2 | 1.0 |
| 9 | β Vacek MathiasLidl-Trek | 1.9 | 1.2 | 1.8 | 5.5 | 10.6 | 0.2 | 1.2 |
The hardest day of the race: 4β5 hours, multiple giant passes β double Ventoux, Granon, Col de la Loze, Bonette.
The archetype, as the model sees it
Built from
| Rider | Blend Win % | Win % | LR Win % | Podium % | Top 5 % | DNF % | Honest Win % | |
|---|---|---|---|---|---|---|---|---|
| 1 | β Pogacar TadejUAE Team Emirates-XRG | 42.9 | 48.6 | 33.2 | 78.6 | 83.6 | 0.6 | 48.6 |
| 2 | β Evenepoel RemcoRed Bull-BORA-hansgrohe | 13.1 | 13.0 | 10.6 | 36.5 | 46.2 | 0.7 | 13.0 |
| 4 | β Seixas PaulDecathlon CMA CGM Team | 10.0 | 8.5 | 8.5 | 15.3 | 24.2 | 1.1 | 8.5 |
| 3 | β Vingegaard JonasTeam Visma | Lease a Bike | 7.8 | 7.2 | 6.4 | 25.6 | 36.6 | 0.6 | 7.2 |
| 5 | β del Toro IsaacUAE Team Emirates-XRG | 6.7 | 3.1 | 6.4 | 11.6 | 21.9 | 0.5 | 3.1 |
| 6 | β Lipowitz FlorianRed Bull-BORA-hansgrohe | 5.0 | 2.9 | 4.6 | 13.6 | 21.6 | 0.4 | 2.9 |
| 10 | β Martinez LennyBahrain Victorious | 2.0 | 1.8 | 1.7 | 5.2 | 9.6 | 0.4 | 1.8 |
| 11 | β Arensman ThymenNetcompany INEOS | 1.8 | 1.5 | 1.5 | 5.9 | 10.7 | 0.4 | 1.5 |
| 7 | β Ayuso JuanLidl-Trek | 1.6 | 1.2 | 1.4 | 6.0 | 9.3 | 0.6 | 1.2 |
| 8 | β Hindley JaiRed Bull-BORA-hansgrohe | 1.6 | 1.2 | 1.4 | 7.0 | 13.0 | 0.5 | 1.2 |
Reading notes
Only two things change between scenarios: the course profile fed to the models (the bars on each card) and the stage-context the DNF head sees. The startlist, every rider's form, Elo, and team context stay identical β so the differences between boards are purely the model's view of rider-course fit. The win books also behave differently by design: the cascade's book is unconstrained (it's a per-rider conditional head), widest on open sprint days and most concentrated when one rider dominates a profile.
The friendly tour
It's a computer program that has studied ten years of professional bike-race results β over 660,000 of them β and uses what it learned to estimate each rider's chances before a race: chance of winning, of finishing on the podium, of making the top 5, and so on.
Think of it like a weather forecast, but for bike races. A forecast doesn't tell you it will definitely rain; it says "70% chance of rain," and a good forecaster is right about 7 times out of 10 when they say that. This system aims for the same thing: percentages you can actually trust, race after race.
Put all ~180 starters in expected finishing order.
Take the top 15 and split the winning chances between them.
A second, more cautious estimate keeps the percentages honest.
Factor in the chance a rider crashes out or quits before the finish.
The team behind the forecast
Under the hood it isn't one big brain β it's a panel of specialists, each trained to answer one question really well. Like a good cycling team, each has a job:
"Roughly where does each rider finish?"
Looks at every starter's history and lines the whole field up in expected finishing order β like a talent scout ranking the startlist from 1 to 180. Whoever lands in its top 15 is treated as a genuine favorite by everyone else on the panel.
"OK, but by how much?"
Two riders can both "lose" a race β one by 2 seconds in a photo finish, the other rolling in 12 minutes later. The Stopwatch predicts the actual time behind the winner, which tells the panel how close the race really was for each rider.
"Of the favorites, who actually wins?"
Ignores everyone except the ~15 genuine favorites and divides the winning chances between them. Opinionated and sharp β this is the specialist that's best at actually naming the winner, and its numbers are the headline percentages in the app.
"Are those percentages actually fair?"
Prices every rider, not just favorites, and its specialty is percentages that mean what they say: across all the riders it gives "10%" to, almost exactly 1 in 10 win. Less flashy than the Tipster, but this is who you'd trust when comparing against a bookmaker.
"Will they even reach the finish?"
About 1 rider in 10 doesn't finish a pro race β crashes, illness, exhaustion, or quitting to save energy for another day. This specialist estimates that risk for each rider, so the other predictions can be adjusted for it.
"Halfway through a 3-week race β now who wins?"
Only wakes up during multi-day races like the Tour de France. Once real stages have been ridden, it uses the actual standings β who's leading, by how many seconds β instead of pretending the race hasn't started yet.
"When it came down to a real fight, who won?"
Keeps a chess-style rating for every rider, but only counts moments that were genuinely contested β a sprint decided at the line, one group distancing another. Beating 50 riders who'd already given up doesn't move your rating; outkicking the world champion does.
"Is the Tipster selling winners short?"
Over thousands of races we measured that the Bold Tipster is slightly too shy about winners' chances. This is a single, carefully measured nudge that corrects for it β like knowing your bathroom scale reads a pound heavy and adjusting accordingly.
"Given the kind of day this is, who belongs in the conversation?"
The newest hire, added after the Tour. Tell it what kind of stage tomorrow is β a mountain-escape day, a split sprint β and it re-picks the shortlist of favorites using ten years of "who actually shows up on days like this." It only decides who's on the shortlist and in what order; it never touches anyone's price.
Worked example
Say it's the morning of a big one-day race, and we follow a star sprinter β call him Rider X β through the whole pipeline:
And here's the important part: the app shows you every one of those numbers, not just the final one. If you want the bold pick, it's there. If you want the cautious price, it's there too. Nothing gets hidden inside the machine.
A fair question
Because they're good at different things β like two friends you'd ask about the race.
One friend is bold: fantastic at calling the winner, but when he says "40% chance," he's often overexcited. The other is careful: her percentages are almost eerily reliable, but she spreads her confidence so evenly that she rarely pounds the table for anyone.
You wouldn't average your friends into one bland opinion and throw away the originals. So the app shows both, plus a blend β and when the two friends disagree strongly about a rider (more than 2 percentage points on the win chance), it highlights that rider in yellow. Big disagreement is useful information: it means "look closer at this one."
New for the Vuelta 2026
The Tour de France was a month-long exam, and the machine mostly passed: bunch sprints and summit finishes were priced well. But it also exposed the one place the machine is structurally weak β the in-between stages, where a breakaway stays away or a late attacker wins from a small group. On those days the pre-race favorites list kept featuring the usual stars, while the actual winner came from a type of rider the boards had buried.
The fix is not new percentages. We tested that thoroughly, and every version of "let the day type change the prices" made the predictions worse. What works is narrower and safer: a menu of eleven day types β mountain-escape day, hard puncheur day, split sprint, survivor's gallop, and so on β each defined by who historically contests the front on days like it, not by the shape of the course.
Each race morning, a human reads the stage and keys it to a menu item (or a weighted mix of two β "60% mountain escape, 40% hard puncheur"). The Casting Director then re-picks the shortlist: riders who thrive on that kind of day move up into the favorites conversation, riders who don't slide out of it. Everything else stays exactly as before β the prices still come from the same specialists, untouched. If the key is wrong, the cost is a worse shortlist for a day, never a corrupted price.
In the dress rehearsal we replayed Tour stage 4 β a hilly stage won from a hard late move β with the key "mountain escape day." The keyed shortlist put Mads Pedersen first (he won it), pulled several eventual breakaway riders up from as deep as 88th, and dropped Tadej PogaΔar down the list while his win price stayed exactly the same. The Vuelta a EspaΓ±a is the live test: every morning's key gets logged before the stage, and every evening it's graded against what actually happened.
Keeping it honest
The model learned by replaying ten years of races under one strict rule: when predicting any race from the past, it's only allowed to use what was knowable the day before that race. No peeking at results that hadn't happened yet β the software equivalent of predicting last Sunday's race using only the previous Saturday's newspaper.
How often does it name the actual winner of a one-day race? About 1 time in 4. If that sounds low, consider: a pro race has ~180 riders, crosswinds, crashes, punctures, and team tactics. Even the bookmakers' favorite usually loses. The real goal isn't naming every winner β it's percentages that hold up over a whole season, so that the riders given "20%" really do win about a fifth of the time. That's the standard every one of the seven specialists is graded against.
And one disclaimer: these are model estimates for research and fun β not betting advice.
The 30-second version
Paste a race URL into the app and it scrapes the startlist, attaches each rider's history as-of today, and runs the field through a stack of models. Each model answers a different question β who's strongest, by how much, will they finish at all β and a final pricing layer turns those answers into a coherent set of sportsbook-style probabilities.
The main line ranks, gates, and prices. Two side lines β a calibration head and a finishing head β join at the pricing layer rather than being averaged in earlier. The GC outlook head runs beside the stack, not through it; the new day-menu channel can re-decide who passes the top-15 gate on a keyed stage day, but never touches a price.
A one-line mental model: the bucket head ranks the field β the cascade prices the top β the corrector fixes its win bias β the blend borrows LambdaRank's calibration β the DNF adjustment makes the prices honest β and every intermediate number stays visible in the table rather than being swallowed by the final one.
The riders on this team
Every head is a LightGBM model, but each differs on three axes: what it predicts, who it compares (the whole field? only contenders? riders who didn't finish?), and what loss it optimizes. Those choices determine what its number means β and why no single head is enough.
Results are scored on a tier scale: winner β podium β top 5 β top 15 β top 30 β top 50 β finisher, referred to below as buckets.
"Roughly where in the result sheet does this rider land?"
The ranking backbone. Predicts a continuous finishing tier for every starter and sorts the field. It is also the gatekeeper: its top 15 defines who counts as a contender everywhere downstream.
"How far behind the winner, in seconds?"
Same ordering intuition as the bucket head, but in physical units β a 2-second gap and a 12-minute gap can be the same tier, and this head knows the difference. That magnitude signal is why its prediction is also fed back into the cascade as a feature.
"Among the genuine contenders, how do the top placings split?"
The headline pricing head. Trained only on gated contenders, with the bucket head's own opinion as an input, it is sharp at separating winner from podium from top 5. Its probabilities are conditional β on being a contender, and on finishing. Drives the displayed Win / Podium / Top 5 / Top 15 % and the odds.
"Over the entire startlist, what's one coherent win book?"
Trained with a learning-to-rank objective and converted to probabilities by a per-race softmax with a fitted temperature. It never beat the cascade at picking winners β but its probabilities are almost perfectly calibrated, which is exactly what you want when comparing against a bookmaker's line.
"Will they finish at all?"
The only head whose training population includes riders who abandoned. Every other probability is implicitly "given that they finish" β this head supplies the missing factor (AUC β 0.89). Applied only at the pricing layer; mixing it into the finish-conditioned heads was tested and made things worse.
"Given the standings after stage k, who wins the overall?"
A state-aware re-run of the main architecture for stage races: it sees each rider's current GC time, rank, and gap. Mid-race it beats simply carrying pre-race predictions forward by ~18 points of winner accuracy. Deliberately shown as its own panel, never merged into the pre-race table.
"How strong is this rider when a result was actually disputed?"
Not a model head but a measurement: an Elo rating built only from informative comparisons β contested sprints within the winner's group, splits between adjacent groups. It enters the models as a feature; the app also shows it raw, with the number of comparisons behind it.
"Is the cascade systematically shy about winners?"
A single fitted parameter, not a model: a logit-scale shift that fixes the cascade's measured win-market under-confidence (validation calibration 0.97 β 1.00 at the last training run). Applied before anything else in the pricing layer.
Team tactics
The cascade doesn't work alone. At training time, out-of-fold predictions from the time-gap and LambdaRank heads are added to its feature set, alongside the contested Elo rating and β for one-day races β contest signatures: a forecast of which kind of rider (sprinter, climber, puncheurβ¦) will actually contest the finish, built from the startlist's composition and the race's history. At prediction time the same 17 columns are attached from the live heads, so training and serving see the same world.
Three post-processing steps, each book-preserving β they reshape who gets which share of probability without inflating the total implied over the field.
The fitted logit shift is applied to contender win probabilities and the odds are recomputed. Deliberately not renormalized β pinning the book here was the root cause of an earlier calibration bug.
The sharp cascade and the calibrated LambdaRank book are combined into a third number, then rescaled so the field's total win probability still matches the cascade's book:
An overlay that borrows LambdaRank's calibration without changing the total vig.
Every market is multiplied by the probability of finishing:
Podium / top-5 / top-15 shrink directly (you can't podium if you don't finish); the win market is renormalized within the race so the total win book is preserved. The result is the price you'd actually want to compare against a bookmaker, whose "did not finish" is just a losing ticket.
The cascade's Win % and LambdaRank's Win % are shown side by side, and any rider where they disagree by 2+ percentage points is highlighted. That disagreement is a feature, not a bug β the two heads carry genuinely different signal, and a large gap is the app telling you to look closer.
Use it to pick winners. Sharpest at separating the very best riders from each other; conditioned on contending and finishing.
Use it to compare against a book. Near-perfectly calibrated across the whole field; the honest baseline for value hunting.
Likewise, the GC outlook stays a separate panel, the Elo rating stays a raw column, and every run β both heads' probabilities, the blend, DNF, adjusted prices β is logged to a prediction database for long-term comparison against real results and real odds.
Reading the app
One table per reference race (plus an averaged tab). Each column traces back to exactly one place in the stack:
| Column | Comes from | How to read it |
|---|---|---|
| Rank Β· Predicted Bucket | Ranking | The field sorted by the bucket head (optionally ensembled with the time-gap head) |
| Expected Bucket | Ranking | Continuous finishing-tier estimate; lower is better |
| Time Gap (s) | Ranking | Predicted seconds behind the winner |
| Contender | Ranking | Inside the bucket head's top 15 β eligible for cascade pricing |
| Win / Podium / Top 5 / Top 15 % | Cascade | Discriminative probabilities, win corrector already applied |
| LR Win / LR Podium % | LambdaRank | Calibrated full-field book; the sportsbook-comparison line |
| Ξ Win pp | Both | Cascade vs LambdaRank disagreement; highlighted at β₯ 2pp |
| Blend Win % | Pricing | 0.2 Γ cascade + 0.8 Γ LambdaRank, book-preserving |
| DNF % | DNF head | Probability of not finishing, given a start |
| Winβ¦Top 15 % (adj) | Pricing | Honest prices: markets Γ probability of finishing |
| Elo Β· Elo n | Rating | Contested-comparison rating and how many duels back it |
| Odds (winβ¦top 30) | Cascade | Decimal / American / fractional, from corrected probabilities |
| GC Outlook panel | GC head | Mid-race only: final-GC probabilities given current standings |
| Keyed board (stage pages) | Retrieval | Board order under the morning's day-type key; pool changes, prices don't |
Everything degrades gracefully. Each head is optional β if an artifact is missing, its columns disappear and a provenance panel says exactly which layers engaged: which references were used, whether live form re-aging ran, whether signatures applied (one-day races only), whether the corrector, DNF head, and blend were active.
The engine room
A weekly pipeline scrapes results from FirstCycling, migrates them into SQLite, and precomputes ~1.1M point-in-time rider snapshots back to 2010 β every feature strictly "as of the day before the race," so the models never peek at the future. Training covers 2016β2026: about 668K rider-race rows across 5,905 competitions at the WorldTour, ProSeries, and .1 levels. The full suite was last retrained on 2026-08-09, on a corpus current through that day β including the complete Tour de France 2026 and a repaired 2025 late-season block (a source-site markup change had silently un-dated 35 races, Vuelta 2025 among them; they were caught, re-scraped, and re-migrated before this training run).
Each rider carries 164 features into a prediction β long-run quality percentiles, recent-form trajectories (recomputed live as of prediction day), team context, race-profile fit against the course's gradients β plus 17 stacked columns (head outputs, contested Elo, contest signatures), for 181 into the flagship ranking head; the day-menu variant adds 14 more. Every prediction run is persisted, so the system continuously builds the dataset needed to judge itself against real books.