NFL · Empirical Bayes

True-Talent Leaderboards

A raw single-season rate is a noisy guess at a player’s real ability, and the noise is worst for the smallest samples — so a naïve leaderboard is topped by whoever got lucky in the fewest tries. This one shrinks every rate toward its position-group prior by how much the sample can be trusted, and shows a 90% credible interval instead of a point. Toggle raw vs. shrunk to watch the flukes fall back to the pack.

EPA per target · 2020

Mean EPA per target, shrunk within position.

Beats raw by
24.4%
lower out-of-sample error
RMSE raw → shrunk
0.38 → 0.29
odd vs. even weeks
Split-half reliability
0.13
how repeatable the raw stat is
Stabilizes at
90
targets to trust the number
shrunkrawthe shrink90% CI
-0.20.00.20.40.6TE avg1Robert TonyanGB · 59+0.432Travis KelceKC · 146+0.403Tyler HigbeeLA · 61+0.374George KittleSF · 64+0.365Irv SmithMIN · 44+0.366Darren FellsHOU · 28+0.367Cameron BrateTB · 34+0.358Richard RodgersPHI · 32+0.349Dan ArnoldARI · 45+0.3410Darren WallerLV · 146+0.3311Adam TrautmanNO · 16+0.3312Jared CookNO · 60+0.3213Ross DwelleySF · 24+0.3214Mark AndrewsBAL · 88+0.3215Pharaoh BrownHOU · 16+0.2916Durham SmytheMIA · 29+0.2917Anthony FirkserTEN · 53+0.2718Tyler KroftBUF · 16+0.2719Austin HooperCLE · 70+0.2620David NjokuCLE · 29+0.2621Albert OkwuegbunamDEN · 15+0.2622Jack DoyleIND · 33+0.2623Jordan AkinsHOU · 49+0.2624Rob GronkowskiTB · 77+0.2625Darrell DanielsARI · 12+0.2626Mo Alie-CoxIND · 39+0.2527Nick BoyleBAL · 17+0.2428Tyler ConklinMIN · 26+0.2429Adam ShaheenMIA · 22+0.2430Geoff SwaimTEN · 12+0.24

Each row is a player: the solid dot is the shrunk estimate, the hollow dot the raw rate, joined by the red pull of regression; the grey bar is the 90% credible interval. A hollow shrunk dot means the sample is below the stabilization line — the number is mostly the position prior. Switch to Raw rank and watch the small-sample names climb.

EPA per target · 2020 · full board

EPA per target leaderboard for the 2020 NFL season, shrunk by empirical Bayes with 90% credible intervals, ranked by the shrunk estimate.
#PlayerTeamPostargetsRawShrunk90% interval
1Robert Tonyan◦ provisionalGBTE59+0.74+0.43+0.22+0.63
2Travis KelceKCTE146+0.52+0.40+0.24+0.56
3Tyler Higbee◦ provisionalLATE61+0.58+0.37+0.16+0.57
4George Kittle◦ provisionalSFTE64+0.57+0.36+0.16+0.56
5Irv Smith◦ provisionalMINTE44+0.66+0.36+0.15+0.58
6Darren Fells◦ provisionalHOUTE28+0.81+0.36+0.13+0.59
7Cameron Brate◦ provisionalTBTE34+0.69+0.35+0.13+0.57
8Richard Rodgers◦ provisionalPHITE32+0.68+0.34+0.12+0.57
9Dan Arnold◦ provisionalARITE45+0.57+0.34+0.12+0.55
10Darren WallerLVTE146+0.39+0.33+0.17+0.49
11Adam Trautman◦ provisionalNOTE16+0.92+0.33+0.09+0.57
12Jared Cook◦ provisionalNOTE60+0.48+0.32+0.12+0.53
13Ross Dwelley◦ provisionalSFTE24+0.69+0.32+0.09+0.55
14Mark Andrews◦ provisionalBALTE88+0.42+0.32+0.13+0.50
15Pharaoh Brown◦ provisionalHOUTE16+0.68+0.29+0.05+0.53
16Durham Smythe◦ provisionalMIATE29+0.48+0.29+0.06+0.51
17Anthony Firkser◦ provisionalTENTE53+0.36+0.27+0.06+0.48
18Tyler Kroft◦ provisionalBUFTE16+0.53+0.27+0.03+0.51
19Austin Hooper◦ provisionalCLETE70+0.32+0.26+0.07+0.46
20David Njoku◦ provisionalCLETE29+0.39+0.26+0.04+0.49
21Albert Okwuegbunam◦ provisionalDENTE15+0.50+0.26+0.02+0.50
22Jack Doyle◦ provisionalINDTE33+0.36+0.26+0.04+0.48
23Jordan Akins◦ provisionalHOUTE49+0.33+0.26+0.05+0.47
24Rob Gronkowski◦ provisionalTBTE77+0.30+0.26+0.07+0.45
25Darrell Daniels◦ provisionalARITE12+0.52+0.26+0.01+0.50
26Mo Alie-Cox◦ provisionalINDTE39+0.33+0.25+0.03+0.47
27Nick Boyle◦ provisionalBALTE17+0.37+0.24+0.00+0.48
28Tyler Conklin◦ provisionalMINTE26+0.30+0.24+0.01+0.47
29Adam Shaheen◦ provisionalMIATE22+0.31+0.24+0.00+0.47
30Geoff Swaim◦ provisionalTENTE12+0.35+0.24-0.01+0.48
31Kaden Smith◦ provisionalNYGTE21+0.29+0.23-0.00+0.47
32Mike Gesicki◦ provisionalMIATE85+0.24+0.23+0.04+0.42
33Jonnu Smith◦ provisionalTENTE66+0.24+0.23+0.03+0.43
34James O'Shaughnessy◦ provisionalJAXTE39+0.24+0.23+0.01+0.45
35Dallas Goedert◦ provisionalPHITE65+0.23+0.22+0.03+0.42
36Marcedes Lewis◦ provisionalGBTE17+0.23+0.22-0.02+0.46
37Jace Sternberger◦ provisionalGBTE15+0.22+0.22-0.02+0.46
38O.J. Howard◦ provisionalTBTE19+0.21+0.22-0.02+0.46
39Ryan Griffin◦ provisionalNYJTE12+0.19+0.22-0.03+0.46
40Will Dissly◦ provisionalSEATE29+0.20+0.22-0.01+0.45
41Kyle Rudolph◦ provisionalMINTE38+0.20+0.22-0.00+0.44
42Jason Witten◦ provisionalLVTE17+0.14+0.21-0.03+0.45
43Hunter HenryLACTE93+0.20+0.21+0.02+0.39
44Donald Parham◦ provisionalLACTE20+0.13+0.20-0.03+0.44
45Blake Bell◦ provisionalDALTE15+0.10+0.20-0.04+0.45
46Jacob Hollister◦ provisionalSEATE41+0.16+0.20-0.01+0.42
47Taysom Hill◦ provisionalNOTE13+0.03+0.20-0.05+0.44
48Hayden Hurst◦ provisionalATLTE89+0.16+0.19+0.01+0.38
49Dalton Schultz◦ provisionalDALTE89+0.15+0.18-0.00+0.37
50Jordan Reed◦ provisionalSFTE46+0.09+0.18-0.03+0.39
51Greg Olsen◦ provisionalSEATE37+0.06+0.17-0.05+0.39
52Noah FantDENTE94+0.12+0.17-0.01+0.35
53Jimmy Graham◦ provisionalCHITE76+0.10+0.17-0.02+0.36
54Drew Sample◦ provisionalCINTE53+0.04+0.16-0.05+0.36
55T.J. HockensonDETTE102+0.10+0.16-0.02+0.33
56Vance McDonald◦ provisionalPITTE20-0.14+0.16-0.08+0.39
57Chris Herndon◦ provisionalNYJTE46+0.02+0.15-0.06+0.37
58Dawson Knox◦ provisionalBUFTE44-0.00+0.15-0.07+0.36
59Cole Kmet◦ provisionalCHITE45-0.02+0.14-0.07+0.36
60Jesse James◦ provisionalDETTE22-0.19+0.14-0.09+0.38
61Troy Fumagalli◦ provisionalDENTE15-0.35+0.14-0.10+0.38
62Nick Vannett◦ provisionalDENTE22-0.22+0.14-0.10+0.37
63Logan ThomasWASTE111+0.06+0.13-0.04+0.31
64Tyler Eifert◦ provisionalJAXTE60-0.02+0.12-0.08+0.33
65Eric EbronPITTE92+0.03+0.12-0.06+0.31
66Ryan Izzo◦ provisionalNETE20-0.33+0.12-0.11+0.36
67Gerald Everett◦ provisionalLATE62-0.02+0.12-0.08+0.32
68Ian Thomas◦ provisionalCARTE31-0.18+0.12-0.11+0.35
69Trey Burton◦ provisionalINDTE47-0.08+0.12-0.10+0.33
70Demetrius Harris◦ provisionalCHITE14-0.56+0.12-0.13+0.36
71N'Keal Harry◦ provisionalNETE57-0.10+0.10-0.11+0.30
72Harrison Bryant◦ provisionalCLETE38-0.27+0.08-0.14+0.30
73Zach Ertz◦ provisionalPHITE73-0.25+0.01-0.18+0.21
74Evan EngramNYGTE109-0.20-0.01-0.18+0.17

How the shrinkage works

Two estimators

Rate stats (completion %, success rate, catch rate) use a beta-binomial model: a Beta(α, β) prior fit by marginal likelihood over each position group, then a Beta posterior per player. Per-play averages (EPA, CPOE, yards) use a normal-normal model with DerSimonian–Laird between-player variance. Both pull each player toward their group by exactly how thin their sample is.

Does it help? & the fine print

The trust panel’s numbers come from a leakage-free odd/even-week holdout: fit on odd weeks, predict even-week raw. Shrinkage lowers out-of-sample error for every stat. Priors are fit per season and per position (WR and TE separately), so a TE’s baseline isn’t a skill. Regular season only, 2016–2025. Rushing and receiving efficiency are heavily scheme-driven — read the wide bands as the honesty they are.

Source: nflverse play-by-play. Counted and computed deterministically — never modeled by a language model. Built by build_nfl_leaderboards.py (byte-reproducible).