Lektion 3: Zufall und Zählen
Baue das Muster „Galtonbrett“ in Python und lerne dabei:
- Zufallszahlen mit np.random.default_rng
- True und False, gezählt als 1 und 0
- Zählen mit np.bincount
- eine List Comprehension
- eine Simulation, mit einer Formel überprüft
Erst ansehen
Läuft nach einem Klick von YouTube.
"""Galton board: every ball goes left or right at random at each of 12 rows of pegs.
Run: python galton-board.py (needs: pip install numpy matplotlib)
"""
from math import comb
import numpy as np
import matplotlib.pyplot as plt
plt.style.use("dark_background")
rows, balls, p = 12, 5000, 0.5 # p: the chance of bouncing right
rng = np.random.default_rng()
bins = (rng.random((balls, rows)) < p).sum(axis=1) # a ball's bin = how often it went right
counts = np.bincount(bins, minlength=rows + 1)
k = np.arange(rows + 1)
expected = [balls * comb(rows, i) * p**i * (1 - p) ** (rows - i) for i in k] # the binomial curve
plt.figure(figsize=(7, 4))
plt.bar(k, counts, color="#5eead4", label="balls")
plt.xlabel("bin = times the ball went right")
plt.plot(k, expected, color="white", label="C(n, k) p^k (1-p)^(n-k)")
plt.legend()
plt.show()
# Try: p = 0.65 tilts the board; rows = 24 makes the bell narrower for its width
Kein Python auf diesem Computer? Das Notebook führt dasselbe Skript, die Übungen und die Lösungen in deinem Browser aus, in Google Colab. Das Notebook ist auf Englisch.
Zeile für Zeile
rng = np.random.default_rng()Der Zufallszahlengenerator von numpy. Gib ihm eine Zahl, default_rng(1), und jeder Lauf ergibt dieselben „zufälligen“ Zahlen.
bins = (rng.random((balls, rows)) < p).sum(axis=1)Eine Tabelle von 5000 × 12 Zufallszahlen zwischen 0 und 1. Jede unter p ist True, ein Sprung nach rechts; die Summe einer Zeile zählt ihre Trues, und das ist das Fach der Kugel.
counts = np.bincount(bins, minlength=rows + 1)Wie viele Kugeln in jedem Fach von 0 bis 12 gelandet sind; minlength sorgt dafür, dass die leeren Randfächer als 0 gezählt werden.
expected = [balls * comb(rows, i) * p**i * (1 - p) ** (rows - i) for i in k]Eine List Comprehension: die Binomialformel für jedes Fach i, mal die Zahl der Kugeln.
plt.bar(k, counts, color="#5eead4", label="balls")Ein Balken pro Fach. Die weiße Linie, die danach gezeichnet wird, ist die Formel, zum Vergleich.
Probier es selbst
Starte das Skript zweimal. Sind die Balken gleich? Dann sorge dafür, dass jeder Lauf gleich ist.
Hinweis
Gib default_rng eine Zahl.
Lösung
Die Balken unterscheiden sich jedes Mal ein wenig. rng = np.random.default_rng(1) ergibt jedes Mal denselben Lauf.
Wie viele von 5000 Kugeln sollten bei 12 Reihen im mittleren Fach landen?
Hinweis
Der Anteil des mittleren Fachs ist comb(12, 6) / 2**12.
Lösung
5000 × 924 ÷ 4096 ≈ 1128.
Kipp das Brett mit p = 0.65. Wo liegt jetzt die Mitte der Glocke?
Hinweis
Die Mitte ist rows · p.
Lösung
12 × 0,65 = 7,8, also wandert der Gipfel zu den Fächern 7 und 8.
Quiz
Lernkarten
Lies die Vorderseite, sag dir die Rückseite vor, dann öffne die Karte.
np.random.default_rng(seed)
Ein Zufallszahlengenerator; derselbe Seed ergibt dieselben Zahlen.
array < 0.5
Ein Array aus True und False; True zählt beim Addieren als 1.
np.bincount(xs)
Wie oft jede ganze Zahl 0, 1, 2, … in xs vorkommt.
[f(i) for i in k]
Eine List Comprehension: eine neue Liste, in der f auf jedes Element von k angewendet ist.
comb(n, k)
Die Zahl der Möglichkeiten, k Dinge aus n auszuwählen: math.comb(12, 6) ist 924.