Again, for this experiment I’m pulling the data from the baseball-reference.com website and this was an no-brainer because you can automatically export the data into columnated excel format that is easy to copy, paste, manipulate and lookup with the model. At this point in the season, the input data is stable enough that it doesn’t need to be updated daily but rather weekly, so every Monday we’ll download and paste the updated results into the model support tabs “Pitching Stats” and “ Batting Stats”.

The other key input data set that was developed for this experiment was the scoring distribution for a Major League Baseball team. This is key for answering the question “well how many runs are we expecting?” which is fundamental if you are betting MLB totals. People have implemented various approaches to this I’m sure but my favorite approach is to put together a distribution based on past results and then when you figure out the percentile you expect from your given team then you look up how many runs correspond to that percentile. Here is the scoring distribution for every team result in baseball from 2016:

What is shown here is that if a team has an offensive performance at the 50th percentile, then based on last year’s games they would be expected to score 4 runs. Similarly an 84th percentile performance (one standard deviation over the median) would result in 7 runs scored and a 16th percentile performance (one standard deviation below the median) would result in 2 runs scored. In the next step we’ll talk about projecting the offensive performance but this is our backbone for our score projection so we will always return a real result when we predict a score (not like 4.3287 runs or something silly).

Generally stated, an average hitting team against average pitching would get you to the 50th percentile, a good hitting team against sorry pitching would get you to the 84th percentile and a lousy hitting team against great pitching would get you to the 16th percentile. Let’s get more specific next…

Step 4: construct the algorithm. For the hardball model we are going to try to calculate two things, the expected number of runs for Team A and the probability of Team A winning. We’ll start with runs scored.

So Team A needs a batting score and we want this score to represent how much better Team A is than an average team at generating runs. For this experiment we’ll start with an advanced batting stat developed by Bill James called “Runs Created”. Ideally we have some parameter that is normalized by the strength of the opponent and is appropriately centered so that an average team against an average pitcher and pen at an average ballpark is projected to perform at the 50th percentile. To center out team batting score, we’ll convert the RC parameter to number of standard deviations better than the average:

So TBS (Team Batting Score) for the Yankees is among the best in the league at 1.788 standard deviations better than the league average, meanwhile Philly is among the league worst at -1.592 standard deviations below the league average. Next we want a composite score for Team B pitchers, for this score we’ll combine the starting pitcher’s individual score (SPS) with the team’s relief pitching score (BPS) using 2/3 weight on the starter (assuming 6 innings pitched) and 1/3 weight on the pen (assuming 3 innings pitched). Still figuring out what advanced stat makes the most sense for starting pitchers but for now using normalized Game Score, again converting it to number of standard deviations away from the average and finally weighting it by the number of games started such that the greater the body of work from a pitcher the stronger the parameter (i.e. the farther from average, either good or bad). Lastly we use normalized runs conceded by the bullpen to develop our BPS.

So if Team A has a TBS of 0.5 and Team B starting pitcher is -1.0 and their bullpen is -0.5 then the total Team B pitching score is -0.833. We’ll combine these two parameters as A_Batting minus B_Pitching over two so Team A Batting 0.5 standard deviation over average facing a Pitching combo conceding almost 1 standard deviation below average we would expect a good amount of runs. We convert (0.5-(-0.833))/2 = 0.667 standard deviations to the 75th percentile using a normal distribution function with a mean of zero and standard deviation of 1. Then looking up our backbone curve we see a 75th percentile runs score is 6 runs. Pretty simple, repeat for Team B facing Team A and let’s say we get 4 runs, then our un-adjusted projection is Team A wins 6–4.

For the win probability we’ll use the tried and true log5 method developed by Bill James to estimate the probability that Team A will win a game given their performance parameter combined with their opponents performance parameter.

Step 5: make adjustments, as necessary. Now we should note a couple things, when implementing a model this simple, adjustments are everything. Right away we need to account for an obvious one that applies in every sport, home field advantage. There are many sophisticated approaches to deal with this but I’m not an expert in complex strategies for baseball so we’ll handle this by giving the home pitcher and home batters a half standard deviation bump to account for the fact that they are playing at home and get to bat last. Ballpark adjustments are another obvious angle that needs to be addressed so we’ll add a ballpark factor to adjust the expected runs for places that are particularly hitter friendly like COL or pitchers parks like LAD. Finally I’m not interested in projecting tie scores so I need to implement a tie-break. To do this we’ll look at the win probability and see which team is more likely to win based on our log5 calc, then adjust that team up a run, or their opponent down a run and in a way that is sort of cheating, we’ll use the lined total to figure out which way we should go (i.e. if the projected tie score is lower than the lined total we’ll add a run to the team with the higher win probability and visa versa).

Step 6: start tracking results. Now as we start to accumulate results it should become obvious that their are other key angles that need to be implemented. You may say “how can you ignore left-handed pitchers throwing against left-handed hitter heavy lineups?” or “what about if a pitcher is making his first start of the season and we don’t have any data on him?”, those are valid questions that we need to eventually account for. But for now we’ll build in manual adjustment “knobs” where we can apply +/- standard deviations to the average to account for situational angles that are apparent. The more important thing is to explore the projected scores to see if there is a systematic bias in the basic algorithm that is favoring home/away teams, underdogs/favs or over/unders. Once we have some confidence that the fundamental algorithm is providing a firm starting point then we can get fancy.

Next Post…

In part 2 we’ll zero in on some of the specific equations and functions that are key in organizing and automizing the process such that you can focus your efforts on finding information that will sharpen your handicap overall and determine the appropriate game-specific adjustments. Until then you can check out the model and it’s results so far here: https://docs.google.com/spreadsheets/d/1lx5CWhM1k4JirYE3khavGelRqoDlHlrmraTeQqOvSbY/edit?usp=sharing

As far as I’m concerned, some model is better than no model and there is no wrong way to use math and statistics to help become a sharper handicap. Best-of-Luck!