Phase 01 - Lesson 06
Probabilidade e Distribuições
This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.
Probabilidade é a linguagem que a IA usa para expressar incerteza.
Tipo: Learn Linguagem: Python Pré-requisitos: Fase 1, Lições 01-04 Tempo: ~75 minutos
Objetivos de Aprendizagem
- Implementar PMFs e PDFs do zero para as distribuições de Bernoulli, categórica, Poisson, uniforme e normal
- Calcular o valor esperado, a variância e usar o Teorema Central do Limite para explicar por que as Gaussianas dominam
- Construir as funções softmax e log-softmax com o truque de estabilidade numérica (subtrair o logit máximo)
- Calcular a perda de entropia cruzada a partir de logits e conectá-la a log-verossimilhança negativa
O Problema
Um classificador retorna [0.03, 0.91, 0.06]. Um modelo de linguagem escolhe a próxima palavra entre 50.000 candidatas. Um modelo de difusão gera imagens amostrando de distribuições aprendidas. Tudo isso é probabilidade em ação.
Toda previsão que um modelo faz é uma distribuição de probabilidade. Toda função de perda mede o quão distante a distribuição prevista está da verdadeira. Todo passo de treinamento ajusta parâmetros para fazer uma distribuição se parecer mais com outra. Sem probabilidade, você não consegue ler um único artigo de ML, depurar um único modelo ou entender por que sua perda de treinamento é NaN.
O Conceito
Eventos, Espaços Amostrais e Probabilidade
O espaço amostral S é o conjunto de todos os resultados possíveis. Um evento é um subconjunto do espaço amostral. A probabilidade mapeia eventos para números entre 0 e 1.
Lancamento de moeda:
S = {H, T}
P(H) = 0.5, P(T) = 0.5
Lancamento de um dado:
S = {1, 2, 3, 4, 5, 6}
P(par) = P({2, 4, 6}) = 3/6 = 0.5
Tres axiomas definem toda a probabilidade:
- P(A) >= 0 para qualquer evento A
- P(S) = 1 (algo sempre acontece)
- P(A ou B) = P(A) + P(B) quando A e B não podem ocorrer juntos
Todo o resto (teorema de Bayes, esperancas, distribuições) decorre dessas três regras.
Probabilidade Condicional e Independência
P(A|B) é a probabilidade de A dado que B aconteceu.
P(A|B) = P(A e B) / P(B)
Exemplo: baralho de cartas
P(Rei | Carta de figura) = P(Rei e Carta de figura) / P(Carta de figura)
= (4/52) / (12/52)
= 4/12 = 1/3
Dois eventos são independentes quando saber um não diz nada sobre o outro:
Independente: P(A|B) = P(A)
Equivalente a: P(A e B) = P(A) * P(B)
Lançamentos de moeda são independentes. Tirar cartas sem reposição não é.
Funções de Massa de Probabilidade vs Funções de Densidade de Probabilidade
Variáveis aleatórias discretas têm uma função de massa de probabilidade (PMF). Cada resultado tem uma probabilidade específica que você pode ler diretamente.
PMF: P(X = k)
Dado justo:
P(X = 1) = 1/6
P(X = 2) = 1/6
...
P(X = 6) = 1/6
Soma de todas as probabilidades = 1
Variáveis aleatórias contínuas têm uma função de densidade de probabilidade (PDF). A densidade em um único ponto não é uma probabilidade. A probabilidade vem de integrar a densidade ao longo de um intervalo.
PDF: f(x)
P(a <= X <= b) = integral de f(x) de a ate b
f(x) pode ser maior que 1 (densidade, nao probabilidade)
integral de -inf a +inf de f(x) dx = 1
Essa distincao importa em ML. Saídas de classificação são PMFs (escolhas discretas). Espaços latentes de VAE usam PDFs (contínuos).
Distribuições Comuns
Bernoulli: um ensaio, dois resultados. Modela classificação binária.
P(X = 1) = p
P(X = 0) = 1 - p
Media = p, Variancia = p(1-p)
Categórica: um ensaio, k resultados. Modela classificação multiclasse (saída softmax).
P(X = i) = p_i, onde a soma de p_i = 1
Exemplo: P(gato) = 0.7, P(cachorro) = 0.2, P(passaro) = 0.1
Uniforme: todos os resultados igualmente prováveis. Usada para inicialização aleatória.
Discreta: P(X = k) = 1/n para k em {1, ..., n}
Continua: f(x) = 1/(b-a) para x em [a, b]
Normal (Gaussiana): a curva em sino. Parametrizada pela média (mu) e variância (sigma^2).
f(x) = (1 / sqrt(2*pi*sigma^2)) * exp(-(x - mu)^2 / (2*sigma^2))
Normal padrao: mu = 0, sigma = 1
68% dos dados dentro de 1 sigma
95% dentro de 2 sigma
99.7% dentro de 3 sigma
Poisson: contagens de eventos raros em um intervalo fixo. Modela taxas de eventos.
P(X = k) = (lambda^k * e^(-lambda)) / k!
Media = lambda, Variancia = lambda
Valor Esperado e Variância
O valor esperado é a média ponderada dos resultados.
Discreta: E[X] = soma de x_i * P(X = x_i)
Continua: E[X] = integral de x * f(x) dx
A variância mede a dispersão em torno da média.
Var(X) = E[(X - E[X])^2] = E[X^2] - (E[X])^2
Desvio padrao = sqrt(Var(X))
Em ML, o valor esperado aparece como a função de perda (perda média sobre a distribuição dos dados). A variância te informa sobre a estabilidade do modelo. Variância alta nos gradientes significa treinamento ruidoso.
Distribuições Conjuntas e Marginais
Uma distribuição conjunta P(X, Y) descreve duas variáveis aleatórias em conjunto.
Exemplo de PMF conjunta (X = clima, Y = guarda-chuva):
| Y=0 (sem guarda-chuva) | Y=1 (com guarda-chuva) | Marginal P(X) | |
|---|---|---|---|
| X=0 (sol) | 0.40 | 0.10 | P(X=0) = 0.50 |
| X=1 (chuva) | 0.05 | 0.45 | P(X=1) = 0.50 |
| Marginal P(Y) | P(Y=0) = 0.45 | P(Y=1) = 0.55 | 1.00 |
A distribuição marginal soma a outra variável:
P(X = x) = soma sobre todo y de P(X = x, Y = y)
Os totais de linha e coluna na tabela acima são as marginais.
Por que a Distribuição Normal Aparece em Todo Lugar
O Teorema Central do Limite: a soma (ou média) de muitas variáveis aleatórias independentes converge para uma distribuição normal, independentemente da distribuição original.
Lance 1 dado: distribuicao uniforme (plana)
Media de 2 dados: triangular (com pico)
Media de 30 dados: curva em sino quase perfeita
Isso funciona para QUALQUER distribuicao inicial.
É por isso que:
- Erros de medição são aproximadamente normais (muitas fontes pequenas e independentes)
- Inicializações de pesos em redes neurais usam distribuições normais
- O ruído do gradiente no SGD é aproximadamente normal (soma de muitos gradientes de amostra)
- A distribuição normal é a distribuição de máxima entropia para uma dada média e variância
Log-Probabilidades
Probabilidades brutas causam problemas numéricos. Multiplicar muitas probabilidades pequenas juntas rapidamente sofre underflow para zero.
P(frase) = P(palavra1) * P(palavra2) * ... * P(palavra_n)
= 0.01 * 0.003 * 0.02 * ...
-> 0.0 (underflow apos ~30 termos)
As log-probabilidades resolvem isso. As multiplicacoes viram somas.
log P(frase) = log P(palavra1) + log P(palavra2) + ... + log P(palavra_n)
= -4.6 + -5.8 + -3.9 + ...
-> numero finito (sem underflow)
Regras:
- log(a * b) = log(a) + log(b)
- log-probabilidades são sempre <= 0 (já que 0 < P <= 1)
- Mais negativo = menos provável
- A perda de entropia cruzada é a log-probabilidade negativa da classe correta
Softmax como Distribuição de Probabilidade
Redes neurais retornam scores brutos (logits). O softmax os converte em uma distribuição de probabilidade valida.
softmax(z_i) = exp(z_i) / sum(exp(z_j) para todo j)
Propriedades:
- Todas as saidas estao em (0, 1)
- Todas as saidas somam 1
- Preserva a ordenacao relativa das entradas
- exp() amplifica diferencas entre logits
O truque do softmax: subtraia o logit máximo antes de exponenciar para evitar overflow.
z = [100, 101, 102]
exp(102) = overflow
z_shifted = z - max(z) = [-2, -1, 0]
exp(0) = 1 (seguro)
Mesmo resultado, sem overflow.
O log-softmax combina softmax e log para estabilidade numérica. O PyTorch usa isso internamente para a perda de entropia cruzada.
Amostragem
Amostragem significa tirar valores aleatórios de uma distribuição. Em ML:
- O dropout amostra aleatoriamente quais neurônios zerar
- A aumentacao de dados amostra transformações aleatórias
- Modelos de linguagem amostram o próximo token da distribuição prevista
- Modelos de difusão amostram ruído e o removem progressivamente
Amostrar de distribuições arbitrárias requer técnicas como amostragem por transformada inversa, amostragem por rejeição ou o truque de reparametrização (usado em VAEs).
Construa
Passo 1: Fundamentos de probabilidade
import math
import random
def factorial(n):
result = 1
for i in range(2, n + 1):
result *= i
return result
def combinations(n, k):
return factorial(n) // (factorial(k) * factorial(n - k))
def conditional_probability(p_a_and_b, p_b):
return p_a_and_b / p_b
p_king_given_face = conditional_probability(4/52, 12/52)
print(f"P(King | Face card) = {p_king_given_face:.4f}")
Passo 2: PMF e PDF do zero
def bernoulli_pmf(k, p):
return p if k == 1 else (1 - p)
def categorical_pmf(k, probs):
return probs[k]
def poisson_pmf(k, lam):
return (lam ** k) * math.exp(-lam) / factorial(k)
def uniform_pdf(x, a, b):
if a <= x <= b:
return 1.0 / (b - a)
return 0.0
def normal_pdf(x, mu, sigma):
coeff = 1.0 / (sigma * math.sqrt(2 * math.pi))
exponent = -0.5 * ((x - mu) / sigma) ** 2
return coeff * math.exp(exponent)
Passo 3: Valor esperado e variância
def expected_value(values, probabilities):
return sum(v * p for v, p in zip(values, probabilities))
def variance(values, probabilities):
mu = expected_value(values, probabilities)
return sum(p * (v - mu) ** 2 for v, p in zip(values, probabilities))
die_values = [1, 2, 3, 4, 5, 6]
die_probs = [1/6] * 6
mu = expected_value(die_values, die_probs)
var = variance(die_values, die_probs)
print(f"Die: E[X] = {mu:.4f}, Var(X) = {var:.4f}, SD = {var**0.5:.4f}")
Passo 4: Amostragem de distribuições
def sample_bernoulli(p, n=1):
return [1 if random.random() < p else 0 for _ in range(n)]
def sample_categorical(probs, n=1):
cumulative = []
total = 0
for p in probs:
total += p
cumulative.append(total)
samples = []
for _ in range(n):
r = random.random()
for i, c in enumerate(cumulative):
if r <= c:
samples.append(i)
break
return samples
def sample_normal_box_muller(mu, sigma, n=1):
samples = []
for _ in range(n):
u1 = random.random()
u2 = random.random()
z = math.sqrt(-2 * math.log(u1)) * math.cos(2 * math.pi * u2)
samples.append(mu + sigma * z)
return samples
Passo 5: Softmax e log-probabilidades
def softmax(logits):
max_logit = max(logits)
shifted = [z - max_logit for z in logits]
exps = [math.exp(z) for z in shifted]
total = sum(exps)
return [e / total for e in exps]
def log_softmax(logits):
max_logit = max(logits)
shifted = [z - max_logit for z in logits]
log_sum_exp = max_logit + math.log(sum(math.exp(z) for z in shifted))
return [z - log_sum_exp for z in logits]
def cross_entropy_loss(logits, target_index):
log_probs = log_softmax(logits)
return -log_probs[target_index]
Passo 6: Demonstração do Teorema Central do Limite
def demonstrate_clt(dist_fn, n_samples, n_averages):
averages = []
for _ in range(n_averages):
samples = [dist_fn() for _ in range(n_samples)]
averages.append(sum(samples) / len(samples))
return averages
Passo 7: Visualização
import matplotlib.pyplot as plt
xs = [mu + sigma * (i - 500) / 100 for i in range(1001)]
ys = [normal_pdf(x, mu, sigma) for x, mu, sigma in ...]
plt.plot(xs, ys)
As implementações completas com todas as visualizações estão em code/probability.py.
Use
Com NumPy e SciPy, tudo acima vira uma linha só:
import numpy as np
from scipy import stats
normal = stats.norm(loc=0, scale=1)
samples = normal.rvs(size=10000)
print(f"Mean: {np.mean(samples):.4f}, Std: {np.std(samples):.4f}")
print(f"P(X < 1.96) = {normal.cdf(1.96):.4f}")
logits = np.array([2.0, 1.0, 0.1])
from scipy.special import softmax, log_softmax
probs = softmax(logits)
log_probs = log_softmax(logits)
print(f"Softmax: {probs}")
print(f"Log-softmax: {log_probs}")
Você construiu tudo isso do zero. Agora você sabe o que as chamadas da biblioteca estão fazendo.
Exercícios
Implemente a amostragem por transformada inversa para a distribuição exponencial. Verifique amostrando 10.000 valores e comparando o histograma com a PDF verdadeira.
Construa uma tabela de distribuição conjunta para dois dados viciados. Calcule as distribuições marginais e verifique se os dados são independentes.
Calcule a perda de entropia cruzada para um classificador de 5 classes que retorna os logits
[2.0, 0.5, -1.0, 3.0, 0.1]quando a classe correta é o índice 3. Depois verifique sua resposta com onn.CrossEntropyLossdo PyTorch.Escreva uma função que recebe uma lista de log-probabilidades e retorna a sequência mais provável, a log-probabilidade total e a probabilidade bruta equivalente. Teste-a com uma frase de 50 palavras onde cada palavra tem probabilidade 0.01.
Termos-Chave
| Termo | O que as pessoas dizem | O que realmente significa |
|---|---|---|
| Espaço amostral | "Todas as possibilidades" | O conjunto S de todo resultado possível de um experimento |
| PMF | "A função de probabilidade" | Uma função que dá a probabilidade exata de cada resultado discreto, somando 1 |
| "A curva de probabilidade" | Uma função de densidade para variáveis contínuas. Integre-a sobre um intervalo para obter a probabilidade | |
| Probabilidade condicional | "Probabilidade dado algo" | P(A|B) = P(A e B) / P(B). A base do raciocínio bayesiano e do teorema de Bayes |
| Independência | "Não se afetam mutuamente" | P(A e B) = P(A) * P(B). Saber um evento não diz nada sobre o outro |
| Valor esperado | "A média" | A soma ponderada por probabilidade de todos os resultados. A função de perda é um valor esperado |
| Variância | "O quão disperso" | O desvio quadrático esperado em relação à média. Variância alta = estimativas ruidosas e instáveis |
| Distribuição normal | "A curva em sino" | f(x) = (1/sqrt(2pisigma^2)) * exp(-(x-mu)^2/(2*sigma^2)). Aparece em todo lugar por causa do TCL |
| Teorema Central do Limite | "Médias viram normais" | A média de muitas amostras independentes converge para uma distribuição normal independentemente da fonte |
| Distribuição conjunta | "Duas variáveis juntas" | P(X, Y) descreve a probabilidade de cada combinação de resultados de X e Y |
| Distribuição marginal | "Some a outra variável" | P(X) = soma_y P(X, Y). Recupera a distribuição de uma variável a partir da conjunta |
| Log-probabilidade | "Log dá a probabilidade" | log P(x). Transforma produtos em somas, evitando o underflow numérico em sequências longas |
| Softmax | "Transforma scores em probabilidades" | softmax(z_i) = exp(z_i) / sum(exp(z_j)). Mapeia logits de valor real para uma distribuição de probabilidade valida |
| Entropia cruzada | "A função de perda" | -sum(p_true * log(p_predicted)). Mede o quão diferentes são duas distribuições. Menor e melhor |
| Logits | "Saídas brutas do modelo" | Scores não normalizados antes do softmax. Nomeado em referência a função logística |
| Amostragem | "Tirar valores aleatórios" | Gerar valores conformé uma distribuição de probabilidade. Como os modelos geram saída |
Leitura Adicional
- 3Blue1Brown: But what is the Central Limit Theorem? - prova visual de por que as médias viram normais
- Stanford CS229 Probability Review - referência concisa cobrindo tudo aqui e mais
- The Log-Sum-Exp Trick - por que a estabilidade numérica importa e como alcançá-la