mlb methodology
MLB Methodology
Four models for four jobs — full-season batter, K/BB/HR components, per-PA matchups, team run totals. All anchored on roughly 10M Statcast pitches.
MLB projections fit four separate models — full-season batter performance, strikeout/walk/homer components, per-plate-appearance matchups, and team run totals — all anchored on roughly 10 million Statcast pitches. The matchup model gives pitcher and batter equal weight because a tough starter swings the line as much as a hot hitter.
engine
Four-model stack: full-season batter + K/BB/HR components + per-PA matchup + team run totals
Each model handles a different prediction horizon. Full-season projections live on the player page. Component models (K%, BB%, HR%) feed the matchup model. The per-PA matchup model gives pitcher and batter equal weight — a tough starter shifts the line as much as a hot bat. Team run totals compose the lineup + bullpen projections.
data
Where the inputs come from
sources
Statcast (Baseball Savant), MLB Stats API, Fielding OAA (Statcast range-based)
training
Roughly 10M Statcast pitches across the Statcast era
holdout
Each model cross-season validated; fielding OAA validated against Gold Glove voting
calibration
Out-of-sample performance
metric
Full-season batter MAE, per-PA matchup Brier, team run-total RMSE, fielding OAA vs. Gold Glove agreement
value
Published per release
Pitcher projections (FIP / K-BB%) validated against Skubal + Skenes seasons. Fielding OAA validated against Gold Glove voting as a face-validity check.
key levers
What controls the projection
Statcast anchor
All four models anchor on Statcast pitch-level data (~10M pitches in training). Without pitch-level granularity, K% and HR% projections drift toward team-context noise.
Equal-weight matchup
In per-PA matchups, pitcher and batter get equal weight in the linear combination. Most public matchup models overweight the recent-hot batter — calibration says equal weight wins.
Per-archetype batter/pitcher aging
Batter archetypes (contact / power / OBP-first) age differently. Pitcher archetypes (starter / high-leverage reliever / mop-up) age differently. Curves fit separately.
Fielding as separate output
Fielding OAA from Statcast range data is a separate per-player output — not folded into batter offense. Position-specific range buckets, not one OAA per player.
faq
Common questions
What's FIP and why do you publish it?
Fielding-Independent Pitching — isolates the pitcher's contribution from defense behind them. We project per-season FIP plus K-BB% because they're the most stable pitcher signals year-to-year.
Do you publish defensive projections?
Yes — fielding OAA is on the /boxes page, derived from Statcast range data. It's validated against Gold Glove voting as a sanity check. Position-specific.
How do you handle pitcher injuries?
Pitcher projections respect IL stints in their starts-projected total. Day-of news (scratched starter, bullpen day) is not chased in the locked projection — that's the live game-prediction engine.
Why equal weight in the matchup model?
Calibration. We tested multiple weight schemes (heavier batter, heavier pitcher, recent-form weighting) and equal weight had the best OOS performance. Most public matchup tools overweight the hot bat.
What about catcher framing?
Framing has its own page (/framing) because it's a catcher-specific skill with non-trivial pitcher-projection implications. We don't fold framing into a single catcher hitting number.
apex framework
For the platform-wide methodology framework — pre-registration policy, data philosophy, bias controls, and honesty notes — see the apex methodology page.