Principiante · Tablero de Galton

Lección 3: Azar y recuento

Construye en Python el patrón «Tablero de Galton» y aprende por el camino:

  • números aleatorios con np.random.default_rng
  • True y False contados como 1 y 0
  • contar con np.bincount
  • una lista por comprensión
  • una simulación comprobada con una fórmula

Míralo primero

Se reproduce desde YouTube tras hacer clic.

galton-board.py
"""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

¿No tienes Python en este equipo? El cuaderno ejecuta el mismo script, los ejercicios y las respuestas en tu navegador, en Google Colab. El cuaderno está en inglés.

Línea a línea

  1. rng = np.random.default_rng()

    El generador de números aleatorios de numpy. Dale un número, default_rng(1), y cada ejecución dará los mismos números «aleatorios».

  2. bins = (rng.random((balls, rows)) < p).sum(axis=1)

    Una tabla de 5000 × 12 números aleatorios entre 0 y 1. Cada uno menor que p es True, un rebote a la derecha; al sumar una fila se cuentan sus True, y esa es la casilla de la bola.

  3. counts = np.bincount(bins, minlength=rows + 1)

    Cuántas bolas cayeron en cada casilla, de la 0 a la 12; minlength se asegura de que las casillas vacías de los bordes cuenten como 0.

  4. expected = [balls * comb(rows, i) * p**i * (1 - p) ** (rows - i) for i in k]

    Una lista por comprensión: la fórmula binomial para cada casilla i, multiplicada por el número de bolas.

  5. plt.bar(k, counts, color="#5eead4", label="balls")

    Una barra por casilla. La línea blanca que se dibuja después es la fórmula, para comparar.

Pruébalo tú

  1. Ejecuta el script dos veces. ¿Son iguales las barras? Después haz que todas las ejecuciones sean iguales.

    Pista

    Dale un número a default_rng.

    Respuesta

    Las barras cambian un poco cada vez. rng = np.random.default_rng(1) da la misma ejecución todas las veces.

  2. ¿Cuántas de 5000 bolas deberían caer en la casilla central con 12 filas?

    Pista

    La proporción de la casilla central es comb(12, 6) / 2**12.

    Respuesta

    5000 × 924 ÷ 4096 ≈ 1128.

  3. Inclina el tablero con p = 0.65. ¿Dónde está ahora el centro de la campana?

    Pista

    El centro es rows · p.

    Respuesta

    12 × 0,65 = 7,8, así que el pico se desplaza a las casillas 7 y 8.

Cuestionario

1. ¿Qué contiene rng.random((5000, 12)) < 0.5?
2. ¿Por qué .sum(axis=1) da la casilla de una bola?
3. ¿Qué da np.bincount([0, 2, 2, 3])?
4. ¿Qué cambia default_rng(1)?
5. En la fórmula binomial, ¿qué parte cuenta los caminos hasta la casilla k?

Tarjetas de repaso

Lee el anverso, di el reverso para ti y luego abre la tarjeta.

  • np.random.default_rng(seed)

    Un generador de números aleatorios; la misma semilla da los mismos números.

  • array < 0.5

    Un array de True y False; True cuenta como 1 al sumar.

  • np.bincount(xs)

    Cuántas veces aparece en xs cada número entero 0, 1, 2, …

  • [f(i) for i in k]

    Una lista por comprensión: una lista nueva con f aplicada a cada elemento de k.

  • comb(n, k)

    El número de maneras de elegir k cosas entre n: math.comb(12, 6) es 924.

Estas tarjetas en su propia página →