Open Projections

A completely transparent methodology for forecasting baseball performance.

Projection Basics

  • Uses game-level stats rather than season-level
  • Projections are updated every day with the past day's stats, year-round
  • Uses stats from the past 2000 days (~6 years)
  • Each stat is weighted and regressed independently
  • Includes every minor league game, as well as all preseason and postseason games
  • Projects over 3000 batters and 3000 pitchers
Current Version: 3.2 (Campanella)

Changelog

  • 3.2 (2021-10-21): Remove post-season PA from playing time projection, as it skews playoff pitchers too much
  • 3.1 (2021-10-09): Bump minimum PA to 400 PA for batters and include post-season PA in playing time projection; rescale pitchers playing time; increased minimum for projection from 10% to 11%
  • 3.0 (2021-10-06): Initial release of Campanella with playing time projections!

Basics

The third version of the Open Projections -- Campanella -- offers a minor update on Version 2 (Blyleven).

The big change is playing time projections. PA/BF are weighted at 0.9955^daysAgo, which heavily favors playing time in the most recent seasons. PA/BF from minor league and spring training games are not counted at all (i.e. weighted at 0).

In order to receive a projection, a player must have at least 11% of the projected PA/BF of the highest projected player. (For this check, PA/BF at any level are counted.) Version 3.0 had the threshold set at 10%, but some NL pitchers were able to sneak a batting projection at that cutoff.

All batters receive a base playing time projection of 400 PA. The batter with the most projected PA is adjusted to 725 PA, and everyone else is scaled accordingly between the min and max.

The pitcher with the most projected BF is adjusted to 850 BF, and everyone else is scaled accordingly. RP below 200 BF are increased by 200, and SP below 400 BF are increased by 400.

Version 2 (Blyleven)

Changelog

  • 2.2 (2021-09-15): Add QS projections for pitchers, using same settings as for W
  • 2.1 (2021-08-19): Update minor league factors. (Previous factors were too high for HR, especially.)
  • 2.0 (2021-08-18): Initial release of Blyleven with separate weighting and regression for each stat!

Basics

The focus of the second iteration of the Open Projections—called Blyleven—is separate weightings and regressions for each component stat in the projection.

We know that some stats (strikeouts, for example) can be projected based on relatively small, recent sample. Other stats (like hits) require a bigger sample and more regression.

This is not a new idea. I'm guessing that this is typical of most closed projection systems. For example:

So, not new, but I'd still guess it's the next best upgrade for the Open Projections.

Weighting by recency

Greater weighting for more recent data, especially for SO, BB, SB, and HR.

Stats for each game are weighted by recency, so that more recent games are more influential in the projection. The weighting is n^daysAgo, where n is a decay rate specific to each stat. (See Aparicio below for additional background and discussion.)

Each stat is weighted separately, depending on how much information is gained by the most recent data. SO are most affected by recent data, followed by walks, SB, and HR. Everything else receives the default weighting from Aparicio (0.9994).

Stat Weights (Batting)

Stat Decay (n)
SO 0.9965
UIBB 0.9974
IBB 0.9974
SB 0.9974
CS 0.9974
HR 0.9985
1B 0.9994
2B 0.9994
3B 0.9994
R 0.9994
RBI 0.9994
HBP 0.9994
SH 0.9994
SF 0.9994
GIDP 0.9994

Pitching stats most biased towards the recent data are SO, then H, and SV/HLD. BB and W/QS slightly favor recent stats, while the rest receive the default 0.9990 from Aparicio.

Stat Weights (Pitching)

Stat Decay (n)
SO 0.9930
H 0.9955
SV 0.9970
HLD 0.9970
HR 0.9980
UIBB 0.9980
HBP 0.9980
W 0.9980
QS 0.9980
R 0.9990
ER 0.9990
L 0.9990
G 0.9990
GS 0.9990
CG 0.9990
SHO 0.9990
WP 0.9990
BK 0.9990
IBB 1.0000

Note: These numbers were not created by an especially rigorous process. They were simply what worked well for projecting past seasons, alongside my own expectations. There is room to improve here.

Weighting by level

(45% for Spring, DT-based stat weights for minors)

Weighting for minor leagues and spring training are unchanged from Aparicio v1.2.

Regression to the mean

(Add n PA of league average for each stat)

Unlike Aparicio, each projected stat in Blyleven is subject to an individualized amount of regression.

There has been a ton of research done in this area:

These studies were used to inform the Blyleven projections, although their different methodologies sometimes yield differing results, and some stats (e.g. SV) were never studied. The final regression amounts were the result of a bit of trial and error. As with the weighting for past results, there ought to be plenty of room for improvement.

For batters, each stat was combined with the following PAs of the league average performance:

Regression Amounts (Batting)

Stat Regression PA
SO 92
UIBB 117
IBB 117
SB 81
CS 81
HR 175
1B 141
2B 354
3B 213
R 281
RBI 214
HBP 120
SH 200
SF 200
GIDP 200

Pitching regression is comparable to hitting, although a player's starts are regressed toward the league average starter, relief appearances toward the league average reliever.

Regression Amounts (Pitching)

Stat Regression BF
SO 70
H 600
SV 100
HLD 100
HR 1200
UIBB 170
HBP 200
W 200
QS 200
R 1200
ER 1200
L 200
G 200
GS 200
CG 200
SHO 200
WP 200
BK 200
IBB 200

R/ER adjustment for pitchers

(an average of projected kwERA and projected ERA)

For pitchers, one extra step is added for Blyleven, borrowing (yet another) idea from the Marcels.

The kwERA is calculated for each pitcher, and then converted to kwER. ER are replaced by a simple average of their previous ER projection and their kwER projection.

Playing time

(650 PA for hitters, 800 BF for SP, 250 BF for RP)

Playing time projections are unchanged from Aparicio v1.1.

That's it!

We're finished! Our Blyleven projections are completed. There's still a lot of room for improvement, but it should be another step in the right direction.

Version 1 (Aparicio)

Changelog

  • 1.2 (2021-08-19): Update minor league factors. (Previous factors were too high for HR, especially.)
  • 1.1 (2021-08-07): Project RP at 250 BF and SP at 800 BF. (Previously both projected to 650 BF.)
  • 1.0 (2021-03-31): Aparicio initial release!

Basics

The inaugural version 1 of the Open Projections—named Aparicio—starts with daily game logs for the past 2000 days (roughly the past six years). By working with daily stats, we are able to build projections for any point in time. A player's projection will gradually shift everyday as the new day's stats are collected and old stats fall out of the projection.

Aparicio includes game data for every level of professional baseball, from Rookie leagues to MLB. It even includes spring training and postseason. We're going to throw everything in the mix and try to filter out the most valuable data.

Weighting by recency

(0.9994^daysAgo for batting, 0.999^daysAgo for pitching)

Stats for each game are weighted by recency, so that more recent games are more influential in the projection. Batting stats are weighted at 0.9994^daysAgo. This means that yesterday's games receive almost full weighting (99.4%), while a game from three years ago counts for about half as much (0.9994^1095 = 51.8%).

Pitching stats are weighted at 0.999^daysAgo. Weighting for both batting and pitching are ideas taken from Tom Tango and are comparable to the yearly weights used by Marcel. (See the discussion of New PECOTA.)

Weighting by level

(45% for Spring, DT-based stat weights for minors)

Spring Training and exhibition games receive a weighting of 45%, a number which comes from Neil Paine's study of spring training stats. (See Neil's When Spring Training Matters and the follow-up discussion by Tom Tango.) Notice this considers the most recent Spring Training as roughly equivalent to MLB performances from three years ago.

No adjustment is made to postseason stats, which are counted the same as the regular season.

For minor league stats, each component receives a separate weight for each level of minor league ball. For this, I did a rough reverse engineering of Clay Davenport's Davenport Translations for 2019. For stats not available in DTs, I approximated with a similar stat (e.g. SV for HLD, BB for HBP). With Version 1.2, I re-ran the Davenport Translation numbers from 2021 and updated the minor league factors.

A more advanced approach would adjust for various minor league park factors and year-by-year changes in league quality. But this is enough to get us started.

Minor League Factors (Batting)

Level AB R H 2B 3B HR RBI SB CS BB SO IBB HBP SH SF GIDP
AAA 1.00 0.79 0.95 0.80 0.84 0.66 0.79 0.72 1.01 0.78 0.90 0.78 0.78 0.78 0.78 0.78
AA/Fall 1.02 0.82 0.99 0.85 0.95 0.67 0.83 0.70 0.91 0.79 0.90 0.79 0.79 0.79 0.79 0.79
High-A 1.03 0.78 0.95 0.79 0.81 0.61 0.75 0.51 0.93 0.72 0.93 0.72 0.72 0.72 0.72 0.72
Low-A 1.05 0.69 0.92 0.76 0.69 0.65 0.68 0.46 0.84 0.64 0.89 0.64 0.64 0.64 0.64 0.64
Rookie 1.08 0.51 0.77 0.63 0.26 0.39 0.48 0.27 0.48 0.54 1.06 0.54 0.54 0.54 0.54 0.54

Minor League Factors (Pitching)

Level W L G GS CG SHO SV HLD BFP IP H ER R HR SO BB IBB HBP WP BK
AAA 0.92 1.14 1.00 1.00 1.00 1.00 0.96 0.96 1.00 1.00 1.13 0.92 0.92 0.88 0.56 0.87 0.87 0.87 0.87 0.87
AA/Fall 0.92 1.24 1.00 1.00 1.00 1.00 0.99 0.99 0.99 0.99 1.25 1.05 1.05 1.02 0.50 0.95 0.95 0.95 0.95 0.95
High-A 0.92 1.31 1.00 1.00 1.00 1.00 0.96 0.96 0.98 0.98 1.28 1.03 1.03 1.28 0.46 0.92 0.92 0.92 0.92 0.92
Low-A 0.86 1.27 1.00 1.00 1.00 1.00 1.04 1.04 1.00 1.00 1.30 1.04 1.04 1.56 0.45 0.89 0.89 0.89 0.89 0.89
Rookie 0.68 1.10 1.00 1.00 1.00 1.00 1.04 1.04 0.96 0.96 1.30 1.08 1.08 2.01 0.38 0.95 0.95 0.95 0.95 0.95

Regression to the mean

(Add average player stats as 15% of the max PA/BF, after removing players with less than 10% of the max PA/BF)

After each player's stats have been weighted, we roll them up into a single statline. Now it's time to regress.

Our regression component will amount to 15% of the PA (or, for pitchers, BF) for the player with the most PA/BF in the sample. For comparison, Marcel uses 1200 PA for its regression. A fixed number of PA, however, doesn't deal well with longer and shorter season lengths (e.g. the shortened season of 2020), so we want to instead use a percentage of PA. With Marcel, a top-of-the-lineup hitter might get 700 PA over the three years Marcel considers. That player would have 8400 PA after Marcel's weighting, and 1200 PA of regression would be about 14% of the total. That's what we are trying to match with our 15% regression.

The regression will be based on the average stats from our universe of players. Before we find the average, though, we discard any players who accumulated less than 10% of the largest number of PA/BF in our set. This clears out pitchers who are hitting, hitters who are pitching, etc. (Question: Should we try to find the average from only MLB stats (i.e. true league average), rather than the average from our universe of players at every level?)

The statline for this average player is added to each player's projected stats.

Playing time

(650 PA for hitters, 800 BF for SP, 250 BF for RP)

For now, playing time projections are kept simple. Every batter's stats are adjusted to exactly 650 PA. Version 1.0 also adjusted every pitcher to 650 BF, but this created obviously unrealistic projections for RP. Version 1.1 tweaks pitcher playing time by setting RP at 250 BF and SP at 800 BF. Pitchers in a mixed role fall in between those two numbers. For example, a pitcher who starts half of his games would be projected halfway between 250 and 800 at 525 BF.

That's it!

We're finished! Our Aparicio projections are completed. Hopefully you can see the many ways that this can still be improved, but it gives us a good starting point.