Blog

ESPN/Yahoo backtest

We dug through old fantasy rankings. The model did not embarrass itself.

We pulled archived preseason category rankings from ESPN, Yahoo Sports articles, and the Wayback Machine, then compared them against our own time-safe projections. The scoreboard: Ball Ranks won seven of eight source-year matchups. The one loss was Yahoo 2025-26, because apparently humility had to be assigned somewhere.

Final rollup
1,438
players compared
7 of 8
matchups won
7.15%
weighted error reduced

The method

Same players, same season, no victory lap math.

We only used ranking boards that looked like standard category or head-to-head category fantasy basketball. Points leagues and salary boards stayed outside, where they belong.

For each source, we matched player names to our database, kept only players who actually reached the 20-game scoring floor, and re-ranked everybody inside that same surviving pool. That matters. Comparing a top-150 list to a full database without trimming the pool is how spreadsheets learn to lie.

The main score is weighted rank miss: top-20 actual finishers count 5x, top-50 count 3x, top-100 count 2x, top-300 count 1x, and deep bench players count 0.5x. Missing a top-10 guy hurts more than missing the 298th guy. Revolutionary stuff, if you have met fantasy basketball.

We also treated the source boards as preseason artifacts, not living documents. ESPN was mostly recovered from archived pages. Yahoo was trickier: the public platform pre-rank pages we found were in-season or postseason, so the clean Yahoo candidates came from Yahoo Sports article pages that embedded Dan Titus category rankings. Not perfect. Better than pretending a December snapshot was a draft board, which would be analytics malpractice wearing a fake mustache.

How much we beat each board by

Positive bars mean Ball Ranks had the smaller weighted rank miss. The teal bar is the one where Yahoo got us. Rude, but fair.

The scoring pool

Every comparison got its own fair little sandbox.

ESPN might rank 150 or 200 players. Yahoo might have 199 or 277. Our model has a full database. Those are not naturally comparable shapes, so we made a shared pool for each source-year.

Example: for ESPN 2023-24, we matched 143 players who also appeared in our scored player file. Then ESPN's order, our projected order, and the final actual order were each re-ranked from 1 to 143 inside that exact pool. Nobody gets credit for ranking a player the other board never had a chance to rank. Very boring. Very necessary.

The held-out 2024-25 season is included only in the expanded companion file used for this article. The original competition residual file stays untouched, because moving the goalposts after the game is frowned upon by most adults and several fantasy commissioners.

Weighted miss, side by side

Orange is Ball Ranks. Teal is the archived ESPN/Yahoo board. Lower is better, because this is fantasy basketball and pain should be smaller.

Ball RanksESPN/Yahoo
11.51%

Error reduced vs ESPN

Across five ESPN boards, our weighted miss was 20.77 ranks. ESPN sat at 23.47. Not a massacre. More like winning by 12 and pretending it was always under control.

2.02%

Error reduced vs Yahoo

Yahoo/FantasyPros was tighter. We still finished ahead overall, but Yahoo 2025-26 clipped us by 1.20 weighted ranks. We have noted this insult in permanent ink.

1,438

Joined player rows

This is not one cherry-picked season. It is eight source-year comparisons after name matching, survival filtering, and re-ranking inside the same pool.

A few receipts

Sometimes the model walked in with the answer key.

These are not cherry-picked from our whole database. They are examples from the same joined ESPN/Yahoo comparison rows used above. A perfect call here means our projected rank and the player's actual finish landed in the same slot inside that source's surviving comparison pool.

PlayerSeasonCall
Victor Wembanyama2024-25actual #3, projected #3
Anthony Davis2024-25actual #4, projected #4
Luka Doncic2025-26actual #6, projected #6
Tyrese Haliburton2024-25actual #7, projected #7
Kristaps Porzingis2023-24actual #10, projected #10

Also, pain

And sometimes the model needed a timeout.

The misses have a theme: role changes, defensive category spikes, and young-player leaps. Translation: the model is pretty good at measuring yesterday and projecting tomorrow, but the NBA still enjoys throwing a chair through the window.

Christian Braun

2024-25

finished #54, projected #267. We would like to thank them for their service and apologize to anyone who drafted responsibly.

Jalen Johnson

2023-24

finished #48, projected #231. We would like to thank them for their service and apologize to anyone who drafted responsibly.

Dyson Daniels

2024-25

finished #25, projected #172. We would like to thank them for their service and apologize to anyone who drafted responsibly.

Kevin Porter Jr.

2025-26

finished #17, projected #207. We would like to thank them for their service and apologize to anyone who drafted responsibly.

So what did we learn?

The model is not magic. It still whiffs on role explosions, defensive-stat jumps, and the occasional player who wakes up one morning as a category monster. But against real archived boards from ESPN and Yahoo, it reduced weighted rank error overall. That is the point: not vibes, not brand names, not a confident paragraph written in September. Tested predictions.

SourceSeasonPlayersError reduced by
ESPN2021-22182+2.23
ESPN2022-23188+1.13
ESPN2023-24143+1.10
Yahoo2023-24244+1.57
ESPN2024-25140+5.61
Yahoo2024-25233+1.03
ESPN2025-26131+3.84
Yahoo2025-26177-1.20

Sample sources