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.
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.
Escolha uma resposta e o seu grau de certeza.
Responda para liberar o experimento.
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.
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.SEdiminui com√n: com quatro vezes mais linhas de teste, cai pela metade.- É maior em
p = 0.5e diminui quandopse aproxima de 0 ou de 1. - Cerca de dois terços das pontuações ficam a menos de um
SEdep, e cerca de 95% a menos de dois. - Esse
SEcobre 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.
Baixar o notebook (.ipynb). Abra no Jupyter ou envie para o Google Colab; ele baixa sozinho os dados que faltarem.
Para quem pratica
- Divida primeiro e só depois ajuste escalonadores e imputadores apenas com as linhas de treino. Um
Pipelinefaz isso por você e mantém as linhas de teste fora de cada etapa ajustada. - Fixe
random_statepara 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.
Isto foi útil?
Obrigado! Isso nos ajuda a melhorar.
Vá mais fundo no Atlas
Verbetes da enciclopédia sobre as ideias desta aula: