La distribución binomial de Poisson y el cálculo del escrutinio

 Doy apertura oficial a este blog con una entrada que considero de las más importantes en el mundo de las quinielas. Se trata de la metodología a seguir para el cálculo de algo tan básico como puede ser la estimación de premios de una determinada columna, y cuyas implicaciones van más allá de simplemente saber, antes del escrutinio oficial, qué premios puedo obtener en caso de encontrarme en categoría.

A partir de un estimador de premios se puede calcular todo. Y me refiero a cuestiones de cálculo de la jugada que voy a realizar. No es una simple curiosidad, ni es algo que se calcule a partir de una base de datos con todas las jugadas registradas en SELAE (Dios sabe que a día de hoy esta información no es pública).

Tener claro qué premios se obtienen a partir de una columna ganadora del sorteo, nos permite saber qué tan rentable es nuestra jugada, a qué premios aspira, cuál es la distribución de premios que nos dará y la probabilidad de cada cifra... De todo esto trataré de ir hablando en futuras entradas porque cada una merece una explicación aparte.

Uno de los métodos más sencillos, y que nos evitan tratar con complejas fórmulas y tener que conocer todas las implicaciones de cada variable del boleto, son las simulaciones. Yo le he encontrado diversos nombres en mis búsquedas de información por la web. Muestreador de Gibbs, Montecarlo (o Monte Carlo), o simplemente simulación. Básicamente consiste en tomar los catorce partidos del boleto (mención aparte del pleno a resultado exacto), y generar un aleatorio para cada uno.

Doy por hecho que la persona que lee esta entrada no parte de cero, y tiene claros conceptos como porcentajes reales, porcentajes apostados, y que el gran beneficio en el mundo de las quinielas proviene de la diferencia entre los dos anteriores.

Como decía, un Montecarlo "simula" cada partido, y lo hace mediante lo que se llama en programación un Random o generador pseudoaleatorio. Cada lenguaje incorpora un paquete que ofrece una función capaz de generar aleatoriamente un número decimal entre 0 y 1. Si sabemos cuál es la probabilidad "real" de que en un partido salga el 1, la X o el 2, podemos simular con una simple línea de código el partido que queramos y las veces que queramos. Basta con lanzar el pseudoaleatorio y ver qué decimales nos ofrece. Si por ejemplo nuestro partido ofrece unos porcentajes del 60-30-10 al 1X2, nos basta saber que si sale por encima de 0'6, y por debajo de 0'9 el resultado de la simulación será un empate. Si generamos catorce signos con las probabilidades de cada uno, tendremos una columna ganadora del sorteo, y si repetimos esto 1.000, 10.000, o mejor aún, 100.000 veces, dispondremos de una muestra estadística que poder analizar y comparar con nuestra jugada. Sin embargo nos falta algo, algo tan esencial como conocer los premios de cada columna ganadora para obtener los valores al cruzarlas con nuestra jugada.

Aquí es donde entra en juego el siguiente método. Lo que comparto a continuación es una función en JS (JavaScript) que puede incorporarse fácilmente a una hoja de cálculo de Google Sheets si, por ejemplo, queremos hacernos un pequeño escrutador de la jornada, aunque como digo su verdadero potencial está orientado a simular miles de veces una jornada o a calcular los valores deseados para nuestra jugada.


function GETQUINIPROBS(percentagesRange, plenoRange, signosRange) {
    var probs = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0];
    var percents = convertTo1(percentagesRange);
    var signos = convertSignos(signosRange);
    var ple = convertTo1(plenoRange);
    var p14 = 1.0;
    for(var a = 0; a < 14; a++) {
      p14 *= percents[a][signos[a]];
      var p13 = 1.0;
      for(var i = 0; i < 14; i++) {
        if(i != a) {
          p13 *= percents[i][signos[i]];
        }
        else {
          p13 *= (1.0 - percents[i][signos[i]]);
        }
      }
      probs[3] += p13;
      for(var b = a + 1; b  14; b++) {
        var p12 = 1.0;
        for(var i = 0; i < 14; i++) {
          if(i != a && i != b) {
            p12 *= percents[i][signos[i]];
          }
          else {
            p12 *= (1.0 - percents[i][signos[i]]);
          }
        }
        probs[2] += p12;
        for(var c = b + 1; c < 14; c++) {
          var p11 = 1.0;
          for(var i = 0; i < 14; i++) {
            if(i != a && i != b && i != c) {
              p11 *= percents[i][signos[i]];
            }
            else {
              p11 *= (1.0 - percents[i][signos[i]]);
            }
          }
          probs[1] += p11;
          for(var d = c + 1; d < 14; d++) {
            var p10 = 1.0;
            for(var i = 0; i < 14; i++) {
              if(i != a && i != b && i != c && i != d) {
                p10 *= percents[i][signos[i]];
              }
              else {
                p10 *= (1.0 - percents[i][signos[i]]);
              }
            }
            probs[0] += p10;
          }
        }
      }
    }
    probs[4] += p14;
    probs[5] = p14 * ple[0][signos[14]] * ple[1][signos[15]];
    return [[probs[0]], [probs[1]], [probs[2]], [probs[3]], [probs[4]], [probs[5]]];
}

function convertSignos(signos) {
  var coordenadas = [];
  for(var i = 0; i < signos.length; i++) {
    if(signos[i] == "1") {
      coordenadas.push(0);
    }
    else if(signos[i] == "X") {
      coordenadas.push(1);
    }
    else if(signos[i] == "0") {
      coordenadas.push(0);
    }
    else if(signos[i] == "M") {
      coordenadas.push(3);
    }
    else if(signos[i] == "2") {
      coordenadas.push(2);
    }
  }
  return coordenadas;
}

function convertTo1(array) {
  var out = [];
  for(var i = 0; i < array.length; i++) {
    var a = [];
    for(var j = 0; j < array[0].length; j++) {
      var value = array[i][j] / 100.0;
      a.push(value);
    }
    out.push(a);
  }
  return out;
}

Comparto también el enlace a una hoja de cálculo de Google donde se puede ver este código en funcionamiento. Tengo que decir que el código está pensado para ser utilizado en una hoja de cálculo, y si deseamos realizar modificaciones, deberemos echar mano al mismo:

https://docs.google.com/spreadsheets/d/1SyFvl9ZXNaWXA1BZNFWbK7c--wi6MetHqCv7cwYehpU/edit?usp=sharing

Aunque voy a explicar a continuación función a función el código JS anterior, queda claro que es necesario tener algún conocimento de algún lenguaje de programación como el mismo JS, Java, C++... Si no es el caso invito al lector a introducirse en el mundo de la programación, ya no para entender ésta y futuras entradas, si no porque es algo apasionante y entretenido (al menos para mí lo es), y porque considero algo imprescindible disponer de algún conocimiento básico de programación e informática en general.

Comienzo explicando la última función convertTo1. Esta función simplemente convierte una entrada en tanto por cien, y la pasa a tanto por uno, para adaptarla al cálculo. Normalmente siempre dispondremos con mayor facilidad de porcentajes en tanto por cien, y suele ser ese el formato manejado por los quinielistas.

La función convertSignos se usa para pasar el formato 1X2, y adicionalmente el 012M del pleno a un código numérico de enteros, donde el 0 es una X y la M pasa a ser un 3. La diferencia entre los 012 del 1X2 y del marcador, se deducen por la posición en la columna.

Finalmente la función del algoritmo (GETQUINIPROBS). Las entradas de esta función son tres matrices, la primera, una matriz de 14x3 que contiene los porcentajes 1X2 apostados en la jornada. La segunda de 2x4 que contiene los porcentajes apostados a cada marcador parcial en el pleno (0-1-2-M), y otra tercera de 16x1 que contiene los resultados de la columna supuestamente ganadora del sorteo. 

Lo que en realidad hace esta función es calcular una distribución binomial de Poisson para la columna ganadora. Esta distribución es de variable discreta, y tan sólo puede tomar determinados valores, 14, 13... 10, 9...1,0 que representan el número de éxitos (14 éxitos máximo en 14 signos, veremos que el pleno se trata distinto).

Si acudimos a la Wikipedia veremos la siguiente fórmula para la distribución binomial de Poisson:

$$\sum_{A \epsilon F_k}\prod_{i \epsilon A}p_i\prod_{j \epsilon A^c}(1 - p_j)$$

No hay que tenerle miedo a la fórmula tal y como está escrita. De hecho yo ni siquiera la entendería, si previamente no hubiera desarrollado el algoritmo, y tan sólo me percaté de su explicación tras entender la suma de probabilidades que obtenía con la fórmula. Y es que se trata de eso, de un sumatorio de un par de productorios. Obviemos los subíndices, superíndices y demás letras que apenas si entendemos a qué hacen referencia. Hay quien sepa de matemáticas y estadística de una manera mucho más profunda, pero para mí supuso todo un desafío dada mi escasa formación en el tema. Todos conocemos el símbolo del sumatorio, y probablemente el productorio. Los subíndices tan sólo nos están indicando qué terminos se suman o se multiplican. Ese "churro" de fórmula nos viene a decir que debemos sumar los productos de las probabilidades de los signos acertados (p sub i) y los fallados (1 - p sub j), pero en todas sus combinaciones. Es decir, para saber la probabilidad de tener 10, 11, 12... aciertos con una columna ganadora, debemos tirar de combinatoria (en este caso mediante bucles anidados en el código) y sumar las probabilidades de todas las columnas posibles con 10, 11, 12... aciertos dada la ganadora. Así de sencillo.

Para aquellos que le echen un vistazo a la hoja de cálculo, les recomiendo que antes de ejecutar saquen una copia personal, revisen el código en el editor de secuencias de Google (en Herramientas), y prueben a cambiar primero, algún signo de la columna ganadora. Está todo un poco desorganizado. La fórmula devuelve una matriz de probabilidades de 10 a 15, posteriormente se usa la recaudación y se relacionan esas probabilidades con la misma, así se obtienen el número de acertantes estimado, y por ende los premios.

No he querido eternizarme en profundas explicaciones, pero espero que al menos haya depositado los ingredientes básicos para que el lector pueda llegar a entender por sí mismo todo lo expuesto. Visita la peña a través de redes, y si me es posible, aclararé las posibles dudas que puedan surgir. Además la web dispone de todo un arsenal de páginas y páginas con contenido científico, y sólo hay que remangarse y hacer algo de búsqueda hipertextual. 

Un saludo, y buenas quinielas.

Comentarios

Publicar un comentario

Entradas populares de este blog

Herramienta de análisis

La regresión logística y el cálculo de porcentajes apostados