BayesBall is a small collection of Python modules for modelling probabilistic baseball events
written by: Chris French
version: 0.1.0 Pre-Alpha
BayesBall is a small collection of Python modules for modelling the probabilistic events that occur in a typical game of baseball. Events, for example, like pitching a baseball, catching a baseball, or stealing home.
Events are modeled with the BayesAction
class. Every BayesAction
is a subclass of ChainMap
with the mappings shown below (ordered from last to first):
GameState
: namedtuple
Environment
: namedtuple
str
subjects
: list
str
str
subjects
: dict
Every BayesAction
determines values for prior probabilities defined over a finite set of action outcomes.
These outcomes and prior probabilities are not intended to be directly changed by the developer. Instead, probability values are initialized (relative to the event’s current reference class and action type) and manipulated by the logic internal to a BayesAction
instance.
In other words, prior probability values are fixed by the logic encapsulated within BayesAction
class methods.
This is a feature, not a bug.
Ideally, BayesAction
instances should behave semi-autonomously. The average modeller should never manipulate these prior probabilities directly–but only indirectly, by manipulating the context of an event. That is, by altering its reference class: by changing the GameState
and, if possible, the Environment
.
Presently, the underlying logic in the main BayesAction
– PitchEvent
–is unrealistic: it relies too heavily on symmetry assumptions rather than the Environment
and players in the current lineups.
BayesBall is different from baseball simulations that are frequentist in nature: whereas BayesBall fixes prior probabilities explicitly, other simulation engines define event probabilities in terms of relative frequencies. For example, these simulations may calculate the probability that a hit pitch will result in a single by first assuming that, say, at most N (= 100,000) hits will occur over the course of a season. If M is the number of other hit events that could occur during an at-bat (excluding singles), the probability that an at-bat will result in a single, if a hit event must occur, is just
(N-n) / (N+M)
where n is the number of singles which have already occurred in the season.
BayesGame provides a framework for developing a baseball game simulator.
Currently, the only dependencies are NumPy and SciPy.
To install these dependencies, use
pip3 install numpy
and
pip3 install scipy
and that’s it. Aside from Python’s curses library, there are no other dependencies.
To play through a toy baseball game example, simply run:
python3 game.py
If you are using Mac/Linux, play through a game with a curses-based app:
python3 app.py
[ ] decide on a systematic way of choosing player attributes, like strength, speed, precision, accuracy, etc.
[ ] determine prior probabilities for pitch/hit outcomes based on player attributes
[ ] add weather conditions
[ ] add game importance conditions, e.g., must win to reach playoffs, wildcard, etc.
[ ] pass the Ball class instance, with spin, velocity, etc.
[x] initialize lead-offs
[x] write player lead-off decision
[x] loop to see if players on base will steal
[x] write player steal decision
[x] write player steal T/F attribute BaseBallPlayer.stealing
[x] write pitcher decision to pick-off
[x] Pitcher’s pickoff location (e.g. ‘first’)
[ ] MUST DO: check for runner collisions.
[ ] MUST DO: timing system …
[x] need to see if a fielder can throw out bunt hit
[x] check to see if a runner is trying to steal, and throw.
[x] check with the catcher to see if a throw should be make, and, if so, check which base the catcher should throw to.
[ ] third strike, catcher drops ball, batter isn’t out…
[ ] give base stealers a benefit for stealing
[ ] force runners to go back if the ball is caught!
[ ] catch success penalties for not good throw results
[ ] write a proper pitch/hit physics based on a physical possibility space, over which an outcome space can be defined. Then define a probability space over this outcome space.
[ ] write a BaseBallGame.manage
method to do things like swapping and substituting players, or more complicated actions, like infield shift, and other strategies dealing with pitcher substitutions, defensive substitutions, resting pitchers, pinch hitters/runners, and so on.
[ ] modify player.py so that a BaseBallPlayer has the following methods:
A method that ranks possible actions based on their expected desirability, relative to the current game state and environment. E.g. if the big HR-hitter is coming up to bat, and the score is tied in the ninth with two outs and two runners on bases, should the pitch walk or pitch to the hitter?
[ ] Store past stats, including past stats relative to batters/pitchers/teams played.