In meinem Land gibt es ein wöchentliches Lottospiel, bei dem die Teilnehmer 6 Zahlen aus einem Pool von 37 und eine weitere Zahl aus einem Pool von 7 auswählen. Konzentrieren wir uns auf den ersten Teil des Spiels und lassen wir die Auswahl einer weiteren Zahl aus einem Pool von 7 außer Acht 7.
Wenn es um Lotterien der Form k/N geht, wobei k die Anzahl der gewünschten Auswahlen (in unserem Fall 6) aus einem Gesamtpool von N Zahlen (in unserem Fall 37) ist, ist eine häufige Frage, ob jede davon Diese Zahlen haben die gleiche Chance, Teil der Gewinnkombination zu sein.
Lassen Sie uns dieser Frage nachgehen.
Ich habe auf ihrer Website Statistiken für 1609 Zeichnungen aus dem Zeitraum 2009 bis 2023 gesammelt.
Anschließend habe ich die Daten aus der CSV-Datei in ein Objekt umgewandelt:
{ '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], ... }
Der Schlüssel im Objekt entspricht dem Datum der Ziehung, und der zugehörige Wert ist ein Array der Zahlen, die als Gewinnkombination für diese bestimmte Ziehung entstanden sind.
Anschließend habe ich ein Array erstellt, das alle aus den Zeichnungen erhaltenen Zahlen enthält:
numbers = np.array(list(lotto.values())).flatten() [13, 17, 24, 30, 35, 37, 7, 17, 19, 25, 35, 37, 2, 3, 5, 9, 36, ...]
Anschließend habe ich die Anzahl der Vorkommen (Häufigkeit) für jeden Wert innerhalb des Arrays berechnet:
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]
Diese Ergebnisse zeigen, dass die Nummer 1 268 Mal gezogen wurde, die Nummer 2 256 Mal und so weiter.
Es scheint, dass die Zahlenverteilung in den Lotterieergebnissen relativ gleichmäßig ist. Um dies weiter zu bestätigen, können wir einen Test durchführen, um die Gleichmäßigkeit der Verteilung zu überprüfen.
Um die Gleichwahrscheinlichkeit der N Einzelzahlen zu testen, können Sie diesem Ansatz folgen:
Führen Sie einen statistischen Test durch, beispielsweise einen Chi-Quadrat-Test, um festzustellen, ob der berechnete Chi-Quadrat-Wert statistisch signifikant ist. Auf diese Weise können Sie beurteilen, ob sich die Verteilung der Zahlen erheblich von dem unterscheidet, was unter Gleichwahrscheinlichkeit zu erwarten wäre.
Wenn der berechnete Chi-Quadrat-Wert statistisch nicht signifikant ist, deutet dies darauf hin, dass die Zahlen einigermaßen gleichmäßig verteilt sind, was die Hypothese der Gleichwahrscheinlichkeit stützt. Wenn der X^2-Wert jedoch signifikant ist, deutet dies auf eine Abweichung von der Gleichwahrscheinlichkeit hin.
Erstellen wir eine Funktion zur Durchführung des Chi-Quadrat-Tests auf Gleichwahrscheinlichkeit von Zahlen:
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
Diese Funktion gibt das Tupel zurück, das aus der Chi-Quadrat-Statistik und dem Ergebnis besteht, dass die Gleichwahrscheinlichkeit mit der Wahrscheinlichkeit 1 - 2 * p-value
angenommen wird, d. h. Extremwerte dieser diskreten Gleichverteilung haben eine geringe Wahrscheinlichkeit.
N = 37 chi2(count, len(numbers), N) (25.183136523720748, True)
Natürlich können Sie die integrierte Funktionalität der SciPy-Bibliothek verwenden, um den Chi-Quadrat-Test für Gleichwahrscheinlichkeit durchzuführen:
from scipy import stats chi2_statistic, p_value = stats.chisquare(count) (25.18313652372074, 0.9115057832606053)
Lassen Sie uns Kombinationen dieser Zahlen untersuchen, beginnend mit Paaren:
from itertools import combinations pairs = list(combinations(range(1, N), 2))
Im Anschluss an diesen Schritt erstellen wir eine 2D-Matrix, die das Vorkommen dieser Paare verfolgt:
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:]
Dies bildet eine Dreiecksmatrix, da sie die Tatsache berücksichtigt, dass Paare (a, b) und (b, a) äquivalent sind und wir nur das Vorkommen der Paare (a, b) zählen.
Meine Funktion ergibt:
counts = pairs_count.flatten() counts = counts[counts > 0] chi2(counts, sum(counts), len(counts)) (589.2721893491138, True)
und SciPy bietet:
chi2_statistic, p_value = stats.chisquare(counts) (589.2721893491124, 0.8698507423203673)
Wie wäre es mit Drillingen:
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)
Etwas ist schief gelaufen, möglicherweise aufgrund der hohen Sparsität der Matrix. Der Chi-Quadrat-Wert fällt unter den unteren kritischen Chi-Quadrat-Schwellenwert:
6457.575829383709 < 6840.049842653838
Bei Verwendung von SciPy ist das Ergebnis jedoch:
chi2_statistic, p_value = stats.chisquare(counts) (6457.575829383886, 0.9999997038479482)
Lassen Sie uns nun die Zahl identifizieren, die am häufigsten gezogen wurde:
count.argmax() or list(count).index(max(count)) 11
Lassen Sie uns noch keine voreiligen Schlüsse ziehen. Wir können untersuchen, wie sich diese Zahl im Laufe der Jahre entwickelt hat:
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 }
Alternativ können wir auch die kumulativen Veränderungen im Zeitverlauf analysieren:
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 }
Abschließend können wir auch untersuchen, ob es jemals identische Zeichnungen gegeben hat:
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 ist amüsant festzustellen, dass sich diese Vorkommnisse fast direkt hintereinander ereigneten.
Am Ende unserer Reise in die Welt der Lotteriedaten war es eine wilde Fahrt durch Zahlen und Wahrscheinlichkeiten. Wir haben einige interessante Leckerbissen entdeckt – von Paaren und Drillingen bis hin zum Erkennen der beliebtesten Zahlen.
Bei Lotterien dreht sich alles um Unvorhersehbarkeit, aber es macht Spaß, einen Blick hinter die Kulissen zu werfen und die Eigenheiten dieser Spiele zu erkunden. Egal, ob Sie ein Spieler oder nur ein neugieriger Beobachter sind, die Welt der Zahlen hält immer die eine oder andere Überraschung bereit.