Simulador de Lineups I: El Codigo

Introducción

Desde hace tiempo he estado programando simuladores de beisbol para resolver diferentes problemas que marca la literatura sabermetricaAcá te explico uno que hice  recientemente para optimizar lineups de un equipo.

Jugadores, const y paquetes

Para que esta herramienta funcione necesitaras descargar tres ficheros:

  1. jugadores.csv: Contiene las métricas de los jugadores que conforman el lineup.
  2. const.py: Encapsula la lógica de movimiento de bases y anotación de carreras por cada evento.
  3. simulador.py: Procesa el fichero jugadores.csv y simula partidos y apariciones al plato con la ayuda const.py.

Jugador outs ubb hbp x1b x2b x3b hr
Jorge Mateo 88 18 0 22 3 1 0
Dairon Blanco 93 11 1 35 3 3 0
Jeimer Candelario 53 12 1 9 9 2 1
Jonah Heim 45 6 0 15 6 1 0
Peter O'Brien 95 33 4 21 9 2 9
Yamaico Navarro 72 21 1 25 5 0 5
Ruben Sosa 67 23 1 29 4 0 0
Anderson Feliz 40 21 1 15 3 0 1
Jordany Valdespin 77 18 3 38 6 0 5
view raw jugadores.csv hosted with ❤ by GitHub

Generar Probabilidades

El archivo simulador.py utiliza la función generarProbs para generar una tabla de probabilidades para cada jugador que se encuentre en el archivo jugadores.csv:

def generarProbs( archivo ):
probs = {}
df = pd.read_csv( archivo )
for idx, row in df.iterrows():
probs[row[0]] = list(row[1:] / sum(row[1:]))
return probs
view raw generarProbs.py hosted with ❤ by GitHub

Simulador de apariciones al plato

La función simularAparicion toma como argumento el nombre de un jugador, genera un numero aleatorio y basado en su tabla de probabilidades calcula el resultado de una aparición al plato.

def simularAparicion( jugador ):
probs_jugador = probs[jugador]
evento = np.random.choice( const.eventos, 1, p = probs_jugador )
return evento[0]
view raw simularAparicion.py hosted with ❤ by GitHub

Simulador de partidos

La función simularPartido simplemente toma un lineup como argumento y simula 9 innings de bateo. Esta función manda a llamar al simulador de apariciones al plato y utiliza la lógica de transición de bases del archivo const.py; Da como resultado el numero de carreras que anotó la alineación y el número de apariciones al plato que ocurrieron en el partido.

def simularPartido( lineup ):
carreras_partido = 0
aparicion = 0
for inning in range( 0, 9 ):
outs = 0
estado = '---'
while outs < 3:
bateador_en_turno = lineup[aparicion % 9]
evento = simularAparicion( bateador_en_turno )
if evento == 'out':
outs += 1
else:
estado = const.transicion[evento][estado]
carreras_partido += const.carreras[evento][estado]
aparicion += 1
return [ carreras_partido, aparicion ]
view raw simularPartido.py hosted with ❤ by GitHub

Correr Simulaciones

La función correrSimulaciones simplemente se encarga de simular los N partidos que desees y de poner los N resultados en un data frame:

def correrSimulaciones( lineup ):
resultado_simulacion = pd.DataFrame( columns = [ 'carreras', 'apariciones', 'carreras_apariciones'] )
for p in range( 0, const.num_simulaciones ):
resultados_partido = simularPartido( lineup )
resultado_simulacion = resultado_simulacion.append( { 'carreras' : resultados_partido[0]
, 'apariciones': resultados_partido[1]
, 'carreras_apariciones': resultados_partido[0] * 100.0 / resultados_partido[1]
}
, ignore_index = True
)
return resultado_simulacion

Para correr el código, simplemente ejecuta estas lineas. En el próximo post de esta serie veremos algunos de los resultados del simulador.

probs = generarProbs('jugadores.csv')
resultados = correrSimulaciones( [ "Ruben Sosa","Jordany Valdespin","Yamaico Navarro","Peter O'Brien","Jeimer Candelario","Jonah Heim","Jorge Mateo","Anderson Feliz","Dairon Blanco" ])
view raw correrTodo.py hosted with ❤ by GitHub

Deja un comentario