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: 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
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”.
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.
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.
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.
plt.bar(k, counts, color="#5eead4", label="balls")Uma barra por compartimento. A linha branca desenhada a seguir é a fórmula, para comparar.
Experimente
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.
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.
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
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.