Trilha 19 · Machine Learning

Regressão linear e gradiente descendente

O "hello world" do ML: ajustar uma reta a pontos. Por trás dela está o gradiente descendente — o mesmo motor que treina desde uma reta até modelos com bilhões de parâmetros.

① Intuição

Descer a colina de olhos fechados

Queremos a reta que melhor passa pelos pontos. "Melhor" significa minimizar o erro total — a soma das distâncias verticais entre a reta e cada ponto, elevadas ao quadrado. Esse erro, em função da inclinação w e do intercepto b, forma uma superfície em forma de tigela: o fundo é a melhor reta.

O gradiente descendente acha o fundo sem ver a tigela inteira. É como descer uma montanha no nevoeiro: você sente a inclinação sob os pés (o gradiente) e dá um passo ladeira abaixo. Repete. O tamanho do passo é a taxa de aprendizado α: passos grandes demais te fazem saltar o vale; pequenos demais, você demora uma eternidade.

Por que o quadrado do erro? Elevar ao quadrado penaliza erros grandes muito mais que pequenos, torna o custo sempre positivo, e — crucialmente — produz uma função suave e convexa (uma única tigela, sem vales falsos). Isso garante que o gradiente descendente sempre encontra o mínimo global na regressão linear.
② Visualização interativa

Treine a reta passo a passo

Clique em "treinar" e veja a reta azul descer até os pontos enquanto os resíduos (linhas laranjas) encolhem e o custo cai. Depois experimente uma taxa de aprendizado α acima de 1.0 e observe o custo explodir em vez de convergir.

xy
ŷ = 2.400·x + 0.050
custo J = 0.2944
iteração 0
CUSTO ↓ POR ITERAÇÃO

Cada passo move w e b na direção oposta ao gradiente do custo — as linhas laranjas (resíduos) encolhem e a reta azul desce até os dados. Tente α alto (>1.0): o custo explode em vez de convergir. α baixo: converge devagar.

③ Explicação técnica

Modelo, custo e gradiente

// Regressão linear: modelo, custo e gradiente

// Modelo (uma feature): previsão é uma reta
//   ŷ = w·x + b      (w = inclinação, b = intercepto)

// Função de custo — Erro Quadrático Médio (MSE):
//   J(w,b) = (1/2m) · Σ (ŷᵢ − yᵢ)²
// Mede o quão longe a reta está dos pontos. Queremos minimizá-la.

def custo(w, b, X, y):
    m = len(X)
    erro = [(w*X[i] + b - y[i])**2 for i in range(m)]
    return sum(erro) / (2*m)

// Gradientes (derivadas parciais do custo):
//   ∂J/∂w = (1/m) · Σ (ŷᵢ − yᵢ)·xᵢ
//   ∂J/∂b = (1/m) · Σ (ŷᵢ − yᵢ)

O laço de gradiente descendente

// Gradiente descendente: descer a colina do custo

def treinar(X, y, alpha=0.1, epocas=1000):
    w, b = 0.0, 0.0
    m = len(X)
    for _ in range(epocas):
        // 1. prever e calcular o erro
        erros = [w*X[i] + b - y[i] for i in range(m)]
        // 2. calcular os gradientes
        dw = sum(erros[i]*X[i] for i in range(m)) / m
        db = sum(erros) / m
        // 3. dar um passo na direção OPOSTA ao gradiente
        w -= alpha * dw
        b -= alpha * db
    return w, b

// alpha (taxa de aprendizado) é decisiva:
//   pequena demais → converge lentíssimo
//   grande demais  → oscila ou diverge (custo explode)

// O mesmo algoritmo treina redes neurais gigantes —
// só muda a função e o número de parâmetros (bilhões).
Batch, mini-batch e SGD: usar todos os exemplos a cada passo (batch) é preciso mas caro com milhões de dados. O gradiente descendente estocástico (SGD) usa um exemplo (ou um pequeno mini-batch) por passo — gradientes ruidosos, porém muito mais rápidos, e o ruído ainda ajuda a escapar de mínimos ruins. Praticamente todo treino de deep learning usa mini-batches (ex: 32, 64, 256 exemplos por passo).
④ Projeto para programar

Implementando do zero

Mini projeto: implemente custo(w,b) e o laço de gradiente descendente em Python puro (sem bibliotecas de ML) para um conjunto de pontos (x,y). Plote a reta a cada 100 épocas e a curva de custo. Confirme que o custo decresce monotonicamente com um α bem escolhido.

Projeto principal: estenda para regressão linear múltipla (várias features) usando vetores do NumPy: ŷ = X·w + b, onde X é uma matriz. Aplique ao dataset de preços de casas (California Housing do sklearn). Importante: normalize as features (subtraia a média, divida pelo desvio) — sem isso, features em escalas diferentes deformam a tigela do custo e o gradiente descendente fica lento.

Desafio extra: compare seu resultado com a solução fechada (equação normal: w = (XᵀX)⁻¹Xᵀy), que dá a resposta exata sem iterar. Depois meça: a partir de quantas features/exemplos o gradiente descendente fica mais rápido que inverter a matriz? (Dica: inverter é O(n³) nas features.)

⑤ Exercícios rápidos

Teste sua intuição

Por que o gradiente descendente subtrai o gradiente dos parâmetros?
Como a taxa de aprendizado α afeta o treino?
Qual a diferença entre gradiente descendente em batch e estocástico (SGD)?
⑥ Aplicações no mundo real

Onde você encontra isso

🏠

Previsão de preços

Zillow, QuintoAndar e seguradoras usam regressão para estimar preços de imóveis e prêmios de seguro a partir de features como área, localização e idade. A interpretabilidade é um bônus: o peso de cada feature diz quanto ela contribui para o preço.

🧠

Treino de redes neurais

O gradiente descendente (via backpropagation) é o algoritmo que treina GPT, Stable Diffusion e todos os grandes modelos. A escala muda — bilhões de parâmetros, milhares de GPUs, variantes como Adam — mas o princípio é idêntico ao desta lição: calcular o gradiente do erro e dar um passo para reduzi-lo.

📈

Econometria e A/B testing

Economistas e times de produto usam regressão para isolar o efeito de uma variável sobre outra (ex: quanto um desconto aumenta vendas, controlando sazonalidade). É a base estatística por trás de boa parte das decisões orientadas por dados em empresas.

← Anterior: O que é ML Próxima: O perceptron →