Hit or Not?
A probabilistic way to use expected statistics in college baseball
Since 2015, Statcast’s measures of batted balls (e.g., exit velocity, launch angle, direction) have been available on Baseball Savant for Major League Baseball (MLB). These data have led to the proliferation of expected statistics (x-stats).
An x-stat describes the probability of a specific outcome given batted ball data. For example, what happens if the ball is struck with an exit velocity of 90 mph and a launch angle of 10°? From 2022–2024, the MLB batting average (AVG) on that ball is 0.586, and slugging percentage (SLG) is 0.637 — in other words, that ball is a hit 58.6% of the time (Figure 1; 94% singles and 6% doubles). MLB has made their x-stats slightly more complicated than that, incorporating average sprint speed (how fast the runner is) and average park factor (how a park’s size, shape, and atmosphere impact ball flight). MLB also reports xBA and xSLG in the same units as their actual metrics AVG and SLG, respectively (e.g., including outcomes for plate appearances that do not result in fair balls).
One of the most common uses of x-stats is to predict whether a batter is under- or over-performing. The concept here is that a batter has a true skill, but due to random noise (luck), they will perform at levels below or above their true skill for variable stretches of time.
If you compare a batter’s xSLG to their SLG and find that their xSLG is higher, you might conclude that they have been unlucky, and that their current SLG underestimates their skill. Sam Bornstein describes this approach in his review of x-stats in the MLB. I think x-stats leave out important parts of the equation, such as defensive alignment (think Albert Pujols’ struggle with the shift), spray direction (Figure 2; the center field wall is always further than the left field wall), and hour-to-hour park factor (walls may not shift, but temperature and wind speed/direction do). Nevertheless, I also think hitting the ball hard and straight is a good recipe for success. So I ask the question: ‘Can we use a revised form of x-stat that is probabilistic and leverages spray direction to achieve more effective player evaluation?’
As usual, I will use D1 college baseball as my crucible. In D1, batted ball data primarily come from TrackMan dual frequency radar systems. Unfortunately, not every D1 stadium is equipped with TrackMan, and some stadiums with TrackMan choose not to share their data with the network. On the other hand, there are so many more D1 teams than MLB teams that in the same ~2 year period, there are about five times more balls in play recorded in D1 than in MLB. I have over 392,000 D1 balls in play to work with.
I do not have access to sprint speed data, and we are still working on developing D1 park factors (stay tuned). On the other hand, I do have spray direction (where on the field the ball is hit), and I have never understood why MLB does not incorporate this valuable information (Figure 2). So in this post, my D1 (and MLB for comparison) x-stats are based entirely on exit velocity, launch angle, and spray direction. Furthermore, I do not (a) include non-batted ball results (e.g., strikeouts and walks) in order to get the x-stat (xBA or xSLG) on the same scale as the traditional stat (AVG or SLG); or (b) remove home runs (BABIP) or singles (ISO) from the stat. Instead, I report xBAfb and xSLGfb as simply the expected AVG and SLG on fair balls.
The next place I diverge from traditional MLB analyses is that I do not collapse each trio of Exit Velocity (EV), Launch Angle (LA), and Spray Direction (SD) into a single mean xBAfb or xSLGfb. Instead, I realize that each {EV,LA,SD} triplet has a distribution of play results that is rich with information. Here is some example output:
Play results for EV = 101.4±1, LA = 21.2±1, SD = -15.8±2:
Fair ball mean: BA = 0.617, SLG = 1.607
Out : 26109
Single : 1359
Double : 26606
Triple : 1554
HomeRun : 12597
Does a mean SLG=1.607 mean mostly singles and doubles with very few outs, or does it mean lots of homers and doubles balanced by nearly as many outs? Just computing a mean statistic can hide so much! Drawing randomly from this distribution of play results 1000 times can more accurately simulate the outcome of a batter’s {EV,LA,SD} triplet from one plate appearance, or from an entire season. This type of approach is called a Monte Carlo simulation, and allows me to place confidence intervals on a batter’s xBAfb or xSLGfb (Figures 4 & 5).
Figures 4 & 5 reveal how two of the top D1 players’ seasons could have gone, suggesting the broader predictive power that comes with knowing the range of possible outcomes for batted ball data. This probabilistic approach teaches us a lot about how a player might perform under more neutral ballpark and defense conditions. If you asked me how I would leverage this new approach to elect my own first-team All Americans or arrange my MLB draft board… I would:
- Adjust xSLGfb for hourly park factor (More on this topic in a future post)
- Recompute the JOPS statistic using xSLGfb as my ultimate measure of player value
- Employ my Bayesian method to account for regression to the mean and assign rigorous confidence intervals on player xJOPS
- Quantitatively compare player xJOPS distributions and report what fraction of the time a particular player ranks 1, 2, or 3 at their position
Since the first-team All Americans have already been chosen, I do not sit in an MLB draft room, and I don’t have D1 park factors (yet), I’ll leave this exercise until next year.
In the meantime, we are putting xBAfb and xSLGfb to other uses at Princeton. We play in the Northeast, and often our first day outside is a game against an ACC school. Our winter season is played indoors in a sub-basement affectionally called ‘the pit.’ The pit has a portable TrackMan and full-sized infield, but then gives way to netting and concrete. During pit scrimmages, it can be hard to judge any hit other than a ground ball, making it hard to run a competitive scrimmage or to evaluate pitchers and hitters. So I designed an app called Hit or Not that runs on an iPhone or iPad and functions exactly like the Python code used in the post (Figure 6).
Now, whether you are in a batting cage, overseeing a scrimmage, or watching a game from the stands, if you can see exit velocity and launch angle information, you can use Hit or Not to determine the likelihood of batted ball events.