ML Atlas

Machine learning do zero · Aula 1.2 · 3 de 33 aulas prontas · 10 min

Dados, atributos, rótulos e divisões

Em resumo

Um conjunto de dados é uma tabela de exemplos, atributos e rótulos. Por que o conjunto de teste fica escondido e quanto o tamanho dele pesa na nota.

Aquecimento Duas perguntas de aulas anteriores. Um minuto, e a aula nunca fica bloqueada.
Da aula 1.1: O que é aprendizado de máquina? Um modelo acerta cerca de 60% das vezes nestes dados de tumores. Por que isso não impressiona?

Ver a resposta

Resposta certa: Porque responder sempre “benigno” já acerta quase dois terços dos casos

A maioria dos tumores do conjunto é benigna, então um modelo precisa superar a resposta majoritária trivial antes de ser útil.

Da aula 1.1: O que é aprendizado de máquina? Você ajusta uma regra até ela acertar todos os exemplos de treino. O que isso diz sobre a próxima paciente?

Ver a resposta

Resposta certa: Muito pouco — só dados que a regra nunca viu mostram como ela lida com casos novos

A acurácia de treino mede o encaixe nos casos conhecidos; só dados reservados estimam o desempenho em casos novos.

Se um professor entrega para a turma exatamente as questões que vão cair na prova final e todo mundo tira nota máxima, o que a prova mediu? A memória daquelas questões, nada mais. O aprendizado de máquina enfrenta esse mesmo problema toda vez, e o jeito de resolvê-lo é surpreendentemente simples: deixar parte das questões trancada numa gaveta.

Preveja, depois confira O mesmo modelo, 20 sorteios diferentes da divisão (30% das biópsias no teste, ou seja, 171). O quanto o resultado no teste muda de um sorteio para outro?
Qual é o seu grau de certeza?

Experimento interativo

Este experimento interativo funciona em um navegador com JavaScript ativado. O texto ao redor descreve o que ele mostra.

Ver a resposta

Resposta certa: Visivelmente: o pior e o melhor sorteio ficam a alguns pontos percentuais um do outro

Com 30% no teste, o resultado oscila de 90,1% a 96,5% (6,4 pontos percentuais), embora o modelo e os dados sejam os mesmos; muda apenas quais biópsias foram parar no teste. Um único resultado de teste, portanto, não é a verdade absoluta.

Experimente

  • Coloque o controle da fração de teste num valor pequeno e depois mova o controle da semente por várias posições. Veja quanto a acurácia de teste muda, mesmo com o modelo e os dados iguais.
  • Agora coloque a fração de teste num valor grande e repita o processo com a semente. A acurácia de teste pula mais ou menos do que antes?
  • Deixe a semente fixa e mova a fração de teste de uma ponta à outra. Repare como o número de linhas de treino encolhe à medida que o conjunto de teste cresce.
  • Encontre a semente que dá a melhor acurácia de teste — e depois pergunte a si mesmo se você poderia divulgar esse número.

A ideia em poucas palavras

Vamos ver agora, em palavras simples, o que você acabou de manipular.

Quase todo conjunto de dados deste curso é uma tabela. Cada linha é um exemplo: um tumor, um paciente, um passageiro, um vinho. Cada coluna é um atributo (em inglês, feature): uma propriedade medida, como um raio, uma pressão arterial, uma idade ou um teor alcoólico. Uma coluna especial guarda o rótulo — a resposta que queremos que o modelo preveja, como “maligno” ou “sobreviveu”. Um modelo é uma regra que leva dos atributos de uma linha ao seu rótulo.

Antes de qualquer aprendizado, as linhas são embaralhadas e divididas. A parte maior, o conjunto de treino, é de onde o modelo aprende. A parte menor, o conjunto de teste, fica trancada e é usada uma única vez, no fim, para estimar como o modelo vai se sair com linhas que nunca viu. Ela faz o papel das questões da gaveta.

Pense numa cozinheira criando uma sopa nova. Ela prova o tempo todo enquanto cozinha — isso é o treino. Mas, para saber se os clientes vão gostar, ela serve a sopa a algumas pessoas que nunca a provaram e não têm motivo nenhum para serem gentis. O veredito delas é a nota de teste. Se ela só perguntasse a si mesma, sempre acharia a sopa perfeita.

Por que funciona

O conjunto de teste só é útil porque o modelo nunca o viu. Desde que as linhas de treino e de teste venham da mesma fonte e tenham sido separadas ao acaso, as linhas de teste se comportam como casos futuros, e a acurácia de teste é uma estimativa justa da acurácia futura.

Mas é só uma estimativa, e esta é a parte que quase ninguém conta para quem está começando. A nota de teste depende de quais linhas caíram no conjunto de teste. Embaralhe os dados com outra semente aleatória e você terá outro conjunto de teste e outra nota — com exatamente o mesmo modelo e os mesmos dados. Com um conjunto de teste pequeno, a nota pode pular bastante, porque um punhado de linhas incomuns pesa muito na porcentagem. A estatística dá um tamanho aproximado para essa oscilação. Para uma acurácia p medida em n linhas de teste, o erro padrão é de aproximadamente

EP ≈ √(p · (1 − p) / n)

ou seja, quadruplicar as linhas de teste só reduz a oscilação pela metade. É por isso que uma única nota de teste nunca é a verdade inteira.

Há também um dilema. Cada linha que você coloca no conjunto de teste é uma linha com a qual o modelo não pode aprender. Um conjunto de teste enorme dá uma nota confiável a um modelo que aprendeu com muito pouco; um conjunto minúsculo dá uma nota pouco confiável a um modelo bem treinado. O mais comum é deixar entre um quinto e um terço das linhas no teste, e as próximas lições mostram jeitos mais espertos de contornar o dilema.

Erro comum

O erro mais tentador é testar várias divisões e ficar com a que dá a nota de teste mais bonita. O conjunto de teste foi então usado para tomar uma decisão, e a nota divulgada fica otimista. Uma versão mais discreta do mesmo erro se chama vazamento de dados (data leakage): informação das linhas de teste escapa para o treino, por exemplo quando você calcula médias para padronizar ou preencher valores ausentes na tabela inteira antes de dividir. A regra é rígida: primeiro divida, depois faça todo o resto usando só as linhas de treino.

Com uma divisão limpa em mãos, finalmente podemos construir um modelo de verdade. Na próxima lição ajustamos o mais simples que existe: uma reta atravessando uma nuvem de pontos.

Quiz

Três perguntas para você se testar. Escolha uma resposta ou abra a resposta embaixo de cada pergunta. No teclado: as setas escolhem, Enter ou Espaço confirma.

1. Por que o conjunto de teste precisa ficar intocado até o fim?
Ver a resposta

Resposta certa: Porque sua nota só vale para dados novos se nenhuma decisão se baseou nele

Assim que o conjunto de teste influencia uma escolha, a nota dele deixa de ser um substituto honesto dos dados futuros.

2. Você muda só a semente aleatória da divisão e a acurácia de teste se mexe. O que isso mostra?
Ver a resposta

Resposta certa: Que uma nota de teste é uma estimativa que depende de quais linhas caíram no conjunto de teste

Sementes diferentes geram linhas de teste diferentes, então a nota varia por acaso, ainda mais com um conjunto de teste pequeno.

3. Qual é o custo de deixar o conjunto de teste muito grande?
Ver a resposta

Resposta certa: O modelo tem menos linhas para aprender

Cada linha que vai para o teste é uma linha com a qual o modelo não aprende, então um teste maior significa um modelo mais mal treinado.

Pontos-chave

  • Um conjunto de dados é uma tabela: linhas são exemplos, colunas são atributos e uma coluna é o rótulo.
  • Divida antes de tudo; o modelo aprende com o conjunto de treino e é avaliado uma única vez no de teste.
  • Uma nota de teste é uma estimativa: outra divisão aleatória dá outro número, principalmente com poucas linhas de teste.
  • Escolher a divisão com a melhor nota, ou preparar os dados na tabela inteira, vaza o conjunto de teste para o treino.

Mais a fundo: fórmula, código, prática

A matemática

A acurácia de teste é uma média de n resultados de acerto ou erro. Se a acurácia verdadeira é p, a pontuação que você mede varia de uma divisão para outra com erro padrão SE ≈ √(p · (1 − p) / n).

  • n é o número de linhas de teste, não o tamanho da tabela inteira.
  • SE diminui com √n: com quatro vezes mais linhas de teste, cai pela metade.
  • É maior em p = 0.5 e diminui quando p se aproxima de 0 ou de 1.
  • Cerca de dois terços das pontuações ficam a menos de um SE de p, e cerca de 95% a menos de dois.
  • Esse SE cobre apenas a escolha das linhas de teste. Não diz nada sobre uma mudança entre os dados que você tem e os que vai encontrar depois.
No código (Python)

A configuração do lab: regressão logística com as 10 variáveis “mean”, 30% das biópsias no conjunto de teste (171 linhas), 20 divisões diferentes:

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

X, y = load_breast_cancer(return_X_y=True, as_frame=True)
X = X.filter(like="mean ")  # as 10 variáveis "mean", como no lab
accs = []
for seed in range(20):  # mesmo modelo, 20 divisões diferentes
    Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.3, stratify=y, random_state=seed)
    model = make_pipeline(StandardScaler(), LogisticRegression()).fit(Xtr, ytr)
    accs.append(model.score(Xte, yte))
n, p = len(yte), float(np.mean(accs))
print(f"test rows: {n}")
print(f"test accuracy: min {min(accs):.1%}, max {max(accs):.1%}")
print(f"standard error: {np.sqrt(p * (1 - p) / n):.1%} (n={n}), {np.sqrt(p * (1 - p) / (4 * n)):.1%} (n={4 * n})")

Saída

test rows: 171
test accuracy: min 90.6%, max 97.1%
standard error: 1.8% (n=171), 0.9% (n=684)

O scikit-learn embaralha de outro jeito que o lab, então o mínimo e o máximo diferem um pouco dos 90,1% e 96,5% do lab. O 684 é hipotético: exige mais linhas do que as 569 dos dados, então só mostra a fórmula. A mensagem é a mesma: a pontuação se move vários pontos com o modelo e os dados inalterados, e quadruplicar as linhas de teste reduz o erro padrão pela metade.

Para quem pratica
  • Divida primeiro e só depois ajuste escalonadores e imputadores apenas com as linhas de treino. Um Pipeline faz isso por você e mantém as linhas de teste fora de cada etapa ajustada.
  • Fixe random_state para que o resultado possa ser repetido, mas escolha-o uma só vez, antes de ver as pontuações. Tentar sementes até uma ficar boa é espiar o conjunto de teste.
  • Na classificação passe stratify=y, para que uma classe rara não desapareça de um conjunto de teste pequeno.
  • Linhas que andam juntas devem ficar juntas. Várias linhas de um mesmo paciente devem ir para o mesmo lado, e dados com ordem temporal devem ser divididos por tempo, não ao acaso. Caso contrário, o conjunto de teste vaza.
  • Informe a pontuação junto com o tamanho do teste e, com poucos dados, repita a divisão ou use validação cruzada (lição 8) para mostrar a dispersão.

Vá mais fundo no Atlas

Verbetes da enciclopédia sobre as ideias desta aula: