El azar y la distribución lognormal

 Ya hemos visto distintas distribuciones estadísticas para diversos aspectos que involucra La Quiniela. En el primer post vimos la Poisson binomial para los premios de una columna, y la loglogística para los retornos de una determinada jugada. Pero lo que vamos a ver ahora es la distribución lognormal aplicada al proceso de azar de una jornada.

La Quiniela no deja de ser un proceso azaroso. Podemos obtener beneficios a largo plazo mediante una esperanza matemática positiva sí, pero el resultado final no deja de ser un simple sorteo. En función de la columna ganadora resultante de dicho sorteo, el importe de premios del escrutinio variará de una a otra cifra, y vamos a ver que esta variación se puede describir también mediante otro tipo de distribución, la lognormal.

La distribución lognormal queda descrita por una variable cuyo logaritmo sigue una ditribución normal. Todos conocemos la distribución normal de alguna clase básica de estadística, es la típica campana de Gauss que hemos visto en multitud de ocasiones referida a su función de densidad.

Para describir la distribución normal, nos basta con dos parámetros, su media, y su desviación estándar. Pues bien, la distribución lognormal se comporta igual, con la salvedad de que esa "normalidad" es referida al logaritmo de la variable. También cambia el rango en que se encuentra definida, de modo que la lognormal sólo admite valores contínuos mayores a cero, mientras que la normal admite cualquier valor real. Además la lognormal, presentará un sesgo hacia la izquierda tal y como se muestra en la imagen.

Como ya mostré en anteriores entradas, nos podemos construir nuestro propio muestreador Montecarlo con código JavaScript. También he enseñado el código necesario para calcular los premios de una determinada columna ganadora. Ambas las he introducido como funciones sueltas en un script para Google Sheets para poder sacar una muestra de 1.000 sorteos para analizar su distribución y compararla con una distribución lognormal. Todo el código se muestra aquí, pero es perfectamente inspeccionable en el propio libro de Google accediendo a "Herramientas -> Editor de secuencias de comandos". Sólo accederemos a esta última sección desde una copia personal, por lo que se debe recordar sacar una copia al propio Drive.


function getPremios(porcentajesRange, signos, recaudacion) {
    var probs = [0.0, 0.0, 0.0, 0.0, 0.0];
    var percents = convertTo1(porcentajesRange);
    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;
    var apuestas = recaudacion / 0.75;
    var premio10;
    if(Math.round(probs[0] * apuestas) == 0) {
      premio10 = Math.round(100.0 * (0.09 * recaudacion) / 1.0) / 100.0
    }
    else {
      premio10 = Math.round(100.0 * (0.09 * recaudacion) / Math.round(probs[0] * apuestas)) / 100.0
    }
    var premio11;
    if(Math.round(probs[1] * apuestas) == 0) {
      premio11 = Math.round(100.0 * (0.075 * recaudacion) / 1.0) / 100.0
    }
    else {
      premio11 = Math.round(100.0 * (0.075 * recaudacion) / Math.round(probs[1] * apuestas)) / 100.0
    }
    var premio12;
    if(Math.round(probs[2] * apuestas) == 0) {
      premio12 = Math.round(100.0 * (0.075 * recaudacion) / 1.0) / 100.0
    }
    else {
      premio12 = Math.round(100.0 * (0.075 * recaudacion) / Math.round(probs[2] * apuestas)) / 100.0
    }
    var premio13;
    if(Math.round(probs[3] * apuestas) == 0) {
      premio13 = Math.round(100.0 * (0.075 * recaudacion) / 1.0) / 100.0
    }
    else {
      premio13 = Math.round(100.0 * (0.075 * recaudacion) / Math.round(probs[3] * apuestas)) / 100.0
    }
    var premio14;
    if(Math.round(probs[4] * apuestas) == 0) {
      premio14 = Math.round(100.0 * (0.16 * recaudacion) / 1.0) / 100.0
    }
    else {
      premio14 = Math.round(100.0 * (0.16 * recaudacion) / Math.round(probs[4] * apuestas)) / 100.0
    }
    return [premio10, premio11, premio12, premio13, premio14];
}

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;
}

function simular(realesRange, apostadosRange, recaudacion, iteraciones) {
  var soluciones = [];
  var pReal = convertTo1(realesRange);
  //Simularemos tantas columnas como deseemos (iteraciones)
  for(var i = 0; i < iteraciones; i++) {
      //Generamos una columna aleatoria por porcentajes
      var columna = simularColumna(pReal);
      //Calculamos las categorías de premios
      var premios = getPremios(apostadosRange, columna, recaudacion);
      //Guardamos la solución en el array de soluciones
      soluciones.push(premios);
  }
  return soluciones;
}

function simularColumna(porcentajes) {
  var signos = [];
  //Simularemos 14 signos a partir de los porcentajes
  for(var i = 0; i < 14; i++) {
    var s = simularSigno(porcentajes[i]);
    signos.push(s);
  }
  return signos;
}

function simularSigno(porcentajesArray) {
  //Creamos el pseudaleatorio
  var val = Math.random();
  //Decidimos qué signo toma de valor. 0 para un 1, 1 para una X, y un 2 para un 2
  if(val < porcentajesArray[0]) {
    return 0;
  }
  else if(val > porcentajesArray[0] && val <= (porcentajesArray[0] + porcentajesArray[1])) {
    return 1;
  }
  else if(val > (porcentajesArray[0] + porcentajesArray[1]) && val <= (porcentajesArray[0] + porcentajesArray[1] + porcentajesArray[2])) {
    return 2;
  }
}

También comparto el enlace a toda la hoja:

https://docs.google.com/spreadsheets/d/1aPQm1zoJLTrjVShx9YsjK9rg6zrvbVpXouQYJTwWVWs/edit?usp=sharing

Con la función "simular" del script, he creado 1.000 sorteos aleatorios en la hoja "Simulacion". También he preparado una hoja "Data" donde tendremos nuestros datos de entrada (reales, apostados, y recaudación). La simulación la he hecho para la jornada 61 de la temporada 2020/21 con los datos finales publicados tras el inicio de la misma.

Para encontrar los parámetros de la lognormal de cada categoría de premios, lo único que debemos hacer es calcular el logaritmo de cada importe, y con las funciones "PROMEDIO" y "DESVEST" podemos hallar la media y la desviación estándar de cada serie. Tan sólo eso, no hace falta nada más, salvo por la dificultad de programar el simulador del script. Los valores de la media y la desviación se muestran en una tabla de la hoja "Parametros" junto con las gráficas que muestran el ajuste entre lo simulado y la solución analítica de la distribución lognormal.

En la hoja "AjusteDistribución" he dispuesto el cálculo de las series para las gráficas. Tanto Excel como las propias Google Sheets disponen de una función que calcula la acumulada de la distribución lognormal para un valor, una media y una desviación dadas, por lo que su uso resulta sencillo. Aún así voy a compartir la fórmula de la distribución lognormal en su forma de función de densidad:

$$\frac{1}{x \sigma \sqrt{2 \pi}}e^{- \frac{(ln x - \mu)^2}{2 \sigma^2}}$$

Integrando la anterior función entre cero y un determinado valor de x en euros, tendremos nuestra probabilidad acumulada.

El motivo por el que no coincide la campana que se podría esperar por anteriores imágenes con la de los gráficos del libro, es que he usado su forma de distribución de probabilidad acumulada, y no la de densidad. Además, he usado una escala logarítmica en el eje X, para que se pueda observar mejor el ajuste entre lo simulado y lo esperado para una lognormal.

Tan sólo he usado la comparación para los premios de 10 y 11 aciertos. A medida que nos acercamos a los 14 signos, la variable contínua que representa la lognormal se va tornando en una variable discreta. Quiero decir con ésto que si hay destinados 30.000€ por ejemplo a la categoría de 13, si hay un acertante se le premiará con esos 30.000, pero si hay dos, el reparto es a 15.000 aunque la lognormal represente cifras entre esas dos cantidades. En todo caso para el acumulado la distribución es adecuada, y podemos afirmar sin demasiado miedo a equivocarnos que los premios por categorías siguen una distribución lognormal para el proceso aleatorio que supone un sorteo.

En la anterior imagen podemos ver el ajuste a la curva teórica para la categoría de 10 aciertos, y comprobar su bondad. Cada vez que abramos el libro todas la fórmulas se recalcularán,  por lo que la línea de simulación sufrirá variaciones, pero también veremos que la simulación va "pegada" a la teórica lognormal en cualquiera de ellas.

La interpretación del anterior gráfico es secilla. Vemos que la mediana, valor en el que el 50% de los valores están por encima y el otro 50% está por debajo, pasa por la cifra de 10€ en la categoría de 10 aciertos. También que el 25% de la veces el premio estará por debajo de 5€ y el 75% por encima. Así es como se interpreta la acumulada, y con ella podemos establecer percentiles para cada cantidad.

Espero, de verdad, que el post haya sido de provecho, y que aunque algún lector no haya entendido todo del primer vistazo, ponga de su parte para indagar en el material complementario, busque toda aquella información que le sea necesaria, y no desista.

Nos vemos en la próxima entrada. Saludos y suerte.

Comentarios

Entradas populares de este blog

Herramienta de análisis

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

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