Básico · Tabuleiro de Galton

Lição 3: Acaso e contagem

Construa em Python o padrão “Tabuleiro de Galton” e aprenda pelo caminho:

  • números aleatórios com np.random.default_rng
  • True e False contados como 1 e 0
  • contar com np.bincount
  • uma compreensão de lista
  • uma simulação comparada com uma fórmula

Veja-o primeiro

É reproduzido a partir do YouTube depois de um clique.

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

Não tem Python neste computador? O notebook executa o mesmo script, os exercícios e as respostas no navegador, no Google Colab. O notebook está em inglês.

Linha a linha

  1. rng = np.random.default_rng()

    O gerador de números aleatórios do numpy. Dê-lhe um número, default_rng(1), e cada execução dá os mesmos números “aleatórios”.

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

    Uma tabela de 5000 × 12 números aleatórios entre 0 e 1. Cada um abaixo de p é True, um desvio para a direita; somar uma linha conta os seus True, e isso é o compartimento da bola.

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

    Quantas bolas caíram em cada compartimento, de 0 a 12; minlength garante que os compartimentos vazios das pontas contam como 0.

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

    Uma compreensão de lista: a fórmula binomial para cada compartimento i, vezes o número de bolas.

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

    Uma barra por compartimento. A linha branca desenhada a seguir é a fórmula, para comparar.

Experimente

  1. Execute o script duas vezes. As barras são iguais? Depois faça com que todas as execuções sejam iguais.

    Pista

    Dê um número a default_rng.

    Resposta

    As barras mudam um pouco de cada vez. rng = np.random.default_rng(1) dá sempre a mesma execução.

  2. Quantas de 5000 bolas deveriam cair no compartimento central com 12 filas?

    Pista

    A parte do compartimento central é comb(12, 6) / 2**12.

    Resposta

    5000 × 924 ÷ 4096 ≈ 1128.

  3. Incline o tabuleiro com p = 0.65. Onde está agora o centro do sino?

    Pista

    O centro é rows · p.

    Resposta

    12 × 0,65 = 7,8, por isso o pico passa para os compartimentos 7 e 8.

Quiz

1. O que contém rng.random((5000, 12)) < 0.5?
2. Por que razão .sum(axis=1) dá o compartimento de uma bola?
3. Quanto é np.bincount([0, 2, 2, 3])?
4. O que muda default_rng(1)?
5. Na fórmula binomial, que parte conta os caminhos até o compartimento k?

Flashcards

Leia a frente, tente recordar o verso e só depois abra o cartão.

  • np.random.default_rng(seed)

    Um gerador de números aleatórios; a mesma semente dá os mesmos números.

  • array < 0.5

    Um array de True e False; ao somar, True conta como 1.

  • np.bincount(xs)

    Quantas vezes cada número inteiro 0, 1, 2, … aparece em xs.

  • [f(i) for i in k]

    Uma compreensão de lista: uma lista nova com f aplicada a cada elemento de k.

  • comb(n, k)

    O número de maneiras de escolher k coisas entre n: math.comb(12, 6) é 924.

Estes flashcards numa página à parte →