Resolve Research
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.

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.

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

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.

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.

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.