paint-brush
Calcula los números de la loteríapor@alexthoughts
20,500 lecturas
20,500 lecturas

Calcula los números de la lotería

por Alex6m2023/10/01
Read on Terminal Reader

Demasiado Largo; Para Leer

Las loterías tienen que ver con la imprevisibilidad, pero es divertido mirar detrás de la cortina y explorar las peculiaridades de estos juegos. Ya seas un jugador o simplemente un observador curioso, el mundo de los números siempre tiene una o dos sorpresas bajo la manga.
featured image - Calcula los números de la lotería
Alex HackerNoon profile picture


En mi país, hay un juego de lotería semanal en el que los participantes seleccionan 6 números de un grupo de 37 y otro número de un grupo de 7. Centrémonos en la primera parte del juego y descartemos la selección de un número adicional de un grupo de 7.


Cuando se trata de loterías de la forma k/N, donde k es el número de selecciones deseadas (en nuestro caso, 6) de un total de N números (en nuestro caso, 37), una pregunta común es si cada uno de estos números tienen las mismas posibilidades de ser parte de la combinación ganadora.


Investiguemos esta cuestión.


Recopilé estadísticas de su sitio web para 1609 dibujos que abarcan desde 2009 hasta 2023.


Posteriormente, convertí los datos del archivo CSV en un objeto:

 { '09/09/2023': [13, 17, 24, 30, 35, 37], '07/09/2023': [7, 17, 19, 25, 35, 37], '05/09/2023': [2, 3, 5, 9, 36, 37], '02/09/2023': [4, 12, 22, 27, 30, 34], '29/08/2023': [6, 8, 15, 19, 26, 31], '26/08/2023': [6, 7, 14, 21, 25, 34], '22/08/2023': [2, 6, 10, 23, 24, 29], ... }


La clave en el objeto corresponde a la fecha del sorteo y el valor asociado es una matriz de números que surgieron como la combinación ganadora para ese sorteo específico.


Luego, creé una matriz que contiene todos los números obtenidos de los dibujos:

 numbers = np.array(list(lotto.values())).flatten() [13, 17, 24, 30, 35, 37, 7, 17, 19, 25, 35, 37, 2, 3, 5, 9, 36, ...]


Después de eso, calculé el recuento de ocurrencias (frecuencia) para cada valor dentro de la matriz:

 count = np.bincount(numbers)[1:] [268, 256, 257, 242, 255, 273, 247, 277, 260, 267, 289, 294, 271, 239, 254, 255, 263, 243, 246, 271, 265, 254, 252, 243, 291, 271, 258, 264, 275, 258, 251, 244, 263, 256, 267, 251, 264]


Estos resultados indican que el número 1 fue extraído 268 veces, el número 2 fue extraído 256 veces, y así sucesivamente.


Parece que la distribución de números en los resultados de la lotería es relativamente uniforme. Para confirmar esto aún más, podemos realizar una prueba para validar la uniformidad de la distribución.


Para probar la equiprobabilidad de los N números individuales, puede seguir este enfoque:


  • Calcule la frecuencia observada (Oi) con la que cada número i = 1,..., N ocurrió en los n sorteos de lotería.


  • Calcule los conteos esperados (Ei) para cada número usando la fórmula Ei = (nk) / N, donde n es el número total de sorteos de lotería, k es el número de números seleccionados en cada sorteo (en este caso, 6) y N es el número total de números posibles (en este caso, 37).


  • Utilice la estadística de Pearson o la estadística chi-cuadrado para comparar los recuentos observados (Oi) con los recuentos esperados (Ei). La fórmula del estadístico de Pearson suele expresarse como:

  • Calcule la estadística de chi-cuadrado utilizando los recuentos observados y esperados.


  • Realice una prueba estadística, como una prueba de chi-cuadrado, para determinar si el valor de chi-cuadrado calculado es estadísticamente significativo. Esto le ayudará a evaluar si la distribución de números es significativamente diferente de lo que se esperaría bajo equiprobabilidad.


Si el valor de chi-cuadrado calculado no es estadísticamente significativo, sugiere que los números están distribuidos razonablemente uniformemente, lo que respalda la hipótesis de equiprobabilidad. Sin embargo, si el valor de X^2 es significativo, indicaría una desviación de la equiprobabilidad.


Creemos una función para realizar la prueba de chi-cuadrado para la equiprobabilidad de números:

 def chi2(data, size, expect, p_value = 0.05): pl = size * 1/expect df = expect - 1 x2_crit_1 = stats.chi2.ppf(p_value, df) x2_crit_2 = stats.chi2.ppf(1 - p_value, df) x2 = 0 for i in range(expect): x2 += ((data[i] - pl) ** 2)/pl accepted = x2_crit_1 < x2 < x2_crit_2 if x2_crit_1 < x2_crit_2 else x2_crit_2 < x2 < x2_crit_1 return x2, accepted


Esta función devuelve la tupla que consta del estadístico chi-cuadrado y el resultado de que la equiprobabilidad se acepta con la probabilidad 1 - 2 * p-value , es decir, los valores extremos de esta distribución uniforme discreta tienen una probabilidad baja.


 N = 37 chi2(count, len(numbers), N) (25.183136523720748, True)


Ciertamente, puede utilizar la funcionalidad incorporada de la biblioteca SciPy para realizar la prueba de equiprobabilidad de chi-cuadrado:

 from scipy import stats chi2_statistic, p_value = stats.chisquare(count) (25.18313652372074, 0.9115057832606053)


Exploremos combinaciones de estos números, comenzando con pares:

 from itertools import combinations pairs = list(combinations(range(1, N), 2))


Después de este paso, construimos una matriz 2D que rastrea las apariciones de estos pares:

 pairs_count = np.zeros([N] * 2, dtype=int) for pair in pairs: for draw in lotto.values(): if pair[0] in draw and pair[1] in draw: pairs_count[pair[0]][pair[1]] += 1 pairs_count = pairs_count[1:, 1:] 



Esto forma una matriz triangular, ya que explica el hecho de que los pares (a, b) y (b, a) son equivalentes, y solo contamos las apariciones de los pares (a, b).


Mi función produce:

 counts = pairs_count.flatten() counts = counts[counts > 0] chi2(counts, sum(counts), len(counts)) (589.2721893491138, True)


y SciPy proporciona:

 chi2_statistic, p_value = stats.chisquare(counts) (589.2721893491124, 0.8698507423203673)


¿Qué tal considerar trillizos?

 comb3 = list(combinations(range(1, N), 3)) comb3_count = np.zeros([N] * 3, dtype=int) for comb in comb3: for draw in lotto.values(): contains = comb[0] in draw and comb[1] in draw and comb[2] in draw if contains: comb3_count[comb[0]][comb[1]][comb[2]] += 1 comb3_count = comb3_count[1:, 1:, 1:] counts = comb3_count.flatten() counts = counts[counts > 0] chi2(counts, sum(counts), len(counts)) (6457.575829383709, False)


Algo salió mal, posiblemente debido a la gran escasez de la matriz. El valor de chi-cuadrado cae por debajo del umbral crítico inferior de chi-cuadrado:

 6457.575829383709 < 6840.049842653838


Sin embargo, al utilizar SciPy, el resultado es:

 chi2_statistic, p_value = stats.chisquare(counts) (6457.575829383886, 0.9999997038479482)


Ahora, identifiquemos el número que ha sido sorteado con mayor frecuencia:

 count.argmax() or list(count).index(max(count)) 11


No saquemos conclusiones precipitadas todavía. Podemos examinar cómo ha evolucionado este número a lo largo de los años:

 year_result = dict() for year in range(2009, 2024): new_dict = {k:v for (k,v) in lotto.items() if str(year) in k} year_result[year] = np.bincount(np.array(list(new_dict.values())).flatten())[1:].argmax() { 2009: 16, 2010: 10, 2011: 11, 2012: 24, 2013: 32, 2014: 34, 2015: 21, 2016: 25, 2017: 5, 2018: 10, 2019: 24, 2020: 11, 2021: 12, 2022: 14, 2023: 11 }


O, alternativamente, podemos analizar los cambios acumulados a lo largo del tiempo:

 year_result = dict() arr = [] for year in range(2009, 2024): new_dict = {k:v for (k,v) in lotto.items() if str(year) in k} arr += list(np.array(list(new_dict.values())).flatten()) year_result['2009 - ' + str(year) if year > 2009 else str(year)] = np.bincount(arr)[1:].argmax() { '2009': 16, '2009 - 2010': 10, '2009 - 2011': 11, '2009 - 2012': 20, '2009 - 2013': 20, '2009 - 2014': 20, '2009 - 2015': 34, '2009 - 2016': 20, '2009 - 2017': 10, '2009 - 2018': 10, '2009 - 2019': 10, '2009 - 2020': 10, '2009 - 2021': 10, '2009 - 2022': 24, '2009 - 2023': 11 }


Por último, también podemos investigar si alguna vez se han producido dibujos idénticos:

 lotto_counts = {} for k, v in lotto.items(): v_str = str(v) if v_str in lotto_counts: lotto_counts[v_str] += [k] else: lotto_counts[v_str] = [k] result = {k: v for k, v in lotto_counts.items() if len(lotto_counts[k]) > 1} { '[13, 14, 26, 32, 33, 36]': ['16/10/2010', '21/09/2010'] }


Es divertido notar que estos sucesos ocurrieron casi uno tras otro.


A medida que concluimos nuestro viaje hacia el mundo de los datos de la lotería, ha sido un viaje salvaje a través de números y probabilidades. Hemos descubierto algunos datos interesantes, desde pares y trillizos hasta detectar los números más populares.


Las loterías tienen que ver con la imprevisibilidad, pero es divertido mirar detrás de la cortina y explorar las peculiaridades de estos juegos. Ya seas un jugador o simplemente un observador curioso, el mundo de los números siempre tiene una o dos sorpresas bajo la manga.