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 · 2019

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
429
targets to trust the number
shrunkrawthe shrink90% CI
0.10.20.30.4TE avg1George KittleSF · 107+0.302Travis KelceKC · 136+0.293Mark AndrewsBAL · 98+0.284Jared CookNO · 65+0.285Taysom HillNO · 22+0.276Darren WallerLV · 117+0.277Hayden HurstBAL · 39+0.278Will DisslySEA · 27+0.269Kyle RudolphMIN · 49+0.2610Darren FellsHOU · 48+0.2611Tyler EifertCIN · 64+0.2612Ryan GriffinNYJ · 43+0.2513Foster MoreauLV · 25+0.2514Tyler HigbeeLA · 89+0.2515Hunter HenryLAC · 77+0.2516Jonnu SmithTEN · 44+0.2517Charles ClayARI · 24+0.2518Dan ArnoldARI · 14+0.2519Benjamin WatsonNE · 24+0.2520Ricky Seals-JonesCLE · 23+0.2521Blake JarwinDAL · 41+0.2522Demetrius HarrisCLE · 28+0.2423James O'Shaughnes…JAX · 20+0.2424Zach ErtzPHI · 136+0.2425Tommy SweeneyBUF · 13+0.2426Austin HooperATL · 99+0.2427Nick BoyleBAL · 44+0.2428Marcedes LewisGB · 19+0.2429Virgil GreenLAC · 13+0.2430Irv SmithMIN · 47+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 · 2019 · full board

EPA per target leaderboard for the 2019 NFL season, shrunk by empirical Bayes with 90% credible intervals, ranked by the shrunk estimate.
#PlayerTeamPostargetsRawShrunk90% interval
1George Kittle◦ provisionalSFTE107+0.54+0.30+0.19+0.40
2Travis Kelce◦ provisionalKCTE136+0.46+0.29+0.19+0.39
3Mark Andrews◦ provisionalBALTE98+0.47+0.28+0.17+0.39
4Jared Cook◦ provisionalNOTE65+0.56+0.28+0.17+0.39
5Taysom Hill◦ provisionalNOTE22+0.96+0.27+0.16+0.39
6Darren Waller◦ provisionalLVTE117+0.40+0.27+0.17+0.38
7Hayden Hurst◦ provisionalBALTE39+0.62+0.27+0.16+0.38
8Will Dissly◦ provisionalSEATE27+0.69+0.26+0.15+0.38
9Kyle Rudolph◦ provisionalMINTE49+0.48+0.26+0.15+0.37
10Darren Fells◦ provisionalHOUTE48+0.46+0.26+0.15+0.37
11Tyler Eifert◦ provisionalCINTE64+0.38+0.26+0.14+0.37
12Ryan Griffin◦ provisionalNYJTE43+0.41+0.25+0.14+0.37
13Foster Moreau◦ provisionalLVTE25+0.52+0.25+0.14+0.37
14Tyler Higbee◦ provisionalLATE89+0.32+0.25+0.14+0.36
15Hunter Henry◦ provisionalLACTE77+0.32+0.25+0.14+0.36
16Jonnu Smith◦ provisionalTENTE44+0.37+0.25+0.14+0.36
17Charles Clay◦ provisionalARITE24+0.44+0.25+0.13+0.36
18Dan Arnold◦ provisionalARITE14+0.55+0.25+0.13+0.36
19Benjamin Watson◦ provisionalNETE24+0.43+0.25+0.13+0.36
20Ricky Seals-Jones◦ provisionalCLETE23+0.42+0.25+0.13+0.36
21Blake Jarwin◦ provisionalDALTE41+0.34+0.25+0.13+0.36
22Demetrius Harris◦ provisionalCLETE28+0.36+0.24+0.13+0.36
23James O'Shaughnessy◦ provisionalJAXTE20+0.37+0.24+0.13+0.36
24Zach Ertz◦ provisionalPHITE136+0.26+0.24+0.14+0.35
25Tommy Sweeney◦ provisionalBUFTE13+0.40+0.24+0.13+0.36
26Austin Hooper◦ provisionalATLTE99+0.26+0.24+0.13+0.35
27Nick Boyle◦ provisionalBALTE44+0.28+0.24+0.13+0.35
28Marcedes Lewis◦ provisionalGBTE19+0.31+0.24+0.12+0.36
29Virgil Green◦ provisionalLACTE13+0.30+0.24+0.12+0.36
30Irv Smith◦ provisionalMINTE47+0.25+0.24+0.13+0.35
31Nick Vannett◦ provisionalPITTE22+0.25+0.24+0.12+0.35
32Jordan Akins◦ provisionalHOUTE55+0.24+0.24+0.13+0.35
33Derek Carrier◦ provisionalLVTE19+0.24+0.24+0.12+0.35
34Josh Hill◦ provisionalNOTE35+0.24+0.24+0.12+0.35
35Kaden Smith◦ provisionalNYGTE43+0.23+0.24+0.12+0.35
36Maxx Williams◦ provisionalARITE19+0.22+0.24+0.12+0.35
37Seth DeValve◦ provisionalJAXTE18+0.22+0.24+0.12+0.35
38Jason Witten◦ provisionalDALTE85+0.23+0.24+0.13+0.34
39Jeff Heuerman◦ provisionalDENTE20+0.19+0.23+0.12+0.35
40Jimmy Graham◦ provisionalGBTE60+0.22+0.23+0.12+0.35
41Ross Dwelley◦ provisionalSFTE22+0.17+0.23+0.12+0.35
42Adam Shaheen◦ provisionalCHITE14+0.12+0.23+0.12+0.35
43Josh Perkins◦ provisionalPHITE13+0.10+0.23+0.12+0.35
44Robert Tonyan◦ provisionalGBTE15+0.11+0.23+0.12+0.35
45Nick O'Leary◦ provisionalJAXTE18+0.10+0.23+0.12+0.35
46Tyler Kroft◦ provisionalBUFTE14+0.03+0.23+0.11+0.35
47O.J. Howard◦ provisionalTBTE53+0.18+0.23+0.12+0.34
48Delanie Walker◦ provisionalTENTE31+0.14+0.23+0.12+0.34
49Dawson Knox◦ provisionalBUFTE50+0.16+0.23+0.12+0.34
50Matt LaCosse◦ provisionalNETE19+0.03+0.23+0.11+0.34
51Hale Hentges◦ provisionalWASTE15-0.04+0.23+0.11+0.34
52T.J. Hockenson◦ provisionalDETTE59+0.15+0.23+0.11+0.34
53N'Keal Harry◦ provisionalNETE24+0.03+0.23+0.11+0.34
54Jesse James◦ provisionalDETTE27+0.02+0.22+0.11+0.34
55Blake Bell◦ provisionalKCTE15-0.18+0.22+0.11+0.34
56Anthony Firkser◦ provisionalTENTE24-0.05+0.22+0.11+0.34
57C.J. Uzomah◦ provisionalCINTE41+0.06+0.22+0.11+0.33
58Durham Smythe◦ provisionalMIATE14-0.28+0.22+0.10+0.34
59Logan Thomas◦ provisionalDETTE28-0.04+0.22+0.10+0.33
60Gerald Everett◦ provisionalLATE60+0.10+0.22+0.11+0.33
61Cameron Brate◦ provisionalTBTE55+0.07+0.22+0.11+0.33
62Greg Olsen◦ provisionalCARTE83+0.11+0.22+0.11+0.32
63Geoff Swaim◦ provisionalJAXTE17-0.35+0.21+0.10+0.33
64Jeremy Sprinkle◦ provisionalWASTE41-0.02+0.21+0.10+0.33
65Dallas Goedert◦ provisionalPHITE87+0.10+0.21+0.11+0.32
66Ian Thomas◦ provisionalCARTE30-0.13+0.21+0.10+0.33
67Jordan Matthews◦ provisionalPHITE12-0.69+0.21+0.09+0.33
68Evan Engram◦ provisionalNYGTE68+0.05+0.21+0.10+0.32
69Jack Doyle◦ provisionalINDTE73+0.03+0.21+0.10+0.32
70Vernon Davis◦ provisionalWASTE19-0.47+0.21+0.09+0.32
71Rhett Ellison◦ provisionalNYGTE28-0.26+0.21+0.09+0.32
72Trey Burton◦ provisionalCHITE24-0.36+0.21+0.09+0.32
73Eric Ebron◦ provisionalINDTE52-0.06+0.21+0.09+0.32
74Noah Fant◦ provisionalDENTE66-0.01+0.20+0.09+0.31
75Luke Stocker◦ provisionalATLTE14-0.87+0.20+0.09+0.32
76Jacob Hollister◦ provisionalSEATE59-0.06+0.20+0.09+0.31
77Mike Gesicki◦ provisionalMIATE89+0.01+0.20+0.09+0.31
78Vance McDonald◦ provisionalPITTE55-0.21+0.19+0.07+0.30

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).