Machine learning do zero · Aula 4.4 · 23 de 33 aulas prontas · 12 min
Engenharia de atributos
Em resumo
A variedade 2 fica no meio do eixo e nenhum limiar a recorta. Uma coluna x² dá 77,4% em vez de 60,4%; 200 colunas de ruído derrubam o kNN de 98,1% para 77,4%.
Aquecimento Duas perguntas de aulas anteriores. Um minuto, e a aula nunca fica bloqueada.
Na lição 4.3 mudamos o jeito de escrever os atributos: a escala dos números e o código das categorias. Hoje criamos atributos novos a partir dos que já temos. A engenharia de atributos consiste em acrescentar colunas que mostram ao modelo com mais clareza o que ele procura: um quadrado, uma razão, uma diferença, o número de dias desde um evento. Um bom atributo pode transformar um problema difícil num fácil. Muitos atributos fracos podem estragar um modelo que funcionava.
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: Não, porque a variedade 2 fica no meio e tem vinhos de outras variedades dos dois lados
Não. No meio do eixo, um limiar sempre deixa uma das outras duas variedades do lado “variedade 2”. O melhor limiar nos vinhos de treino acerta 61,6%, pouco mais que os 60,0% de dizer “outra variedade” para cada vinho, e nos vinhos de teste exatamente o mesmo: 60,4%. A SVM linear do lab não prevê a variedade 2 em lugar nenhum. Só uma coluna nova x² permite recortar o intervalo do meio.
Experimente
- Comece só com x. Onde o modelo prevê a variedade 2? Qual é a acurácia de teste, e de onde ela vem?
- Acrescente a coluna x². Como fica a fronteira no plano (x, x²), e no eixo dos flavonoides sozinho?
- Passe para o ruído. Desça o controle a partir de 200 colunas. Quando o kNN reconhece melhor os vinhos separados?
- Observe o contraste das distâncias. O que acontece com a diferença entre o vinho mais próximo e o mais distante quando as colunas se acumulam?
Depois de conferir no lab, vamos dar nome ao que você vê.
A ideia em palavras simples
Um modelo linear num eixo só sabe fazer uma coisa: pôr um limiar. A variedade 2 fica no meio do eixo dos flavonoides, então um limiar não consegue recortá-la de nenhum lado: separa no máximo uma das variedades vizinhas. O melhor limiar desse tipo separa a variedade 3 e acerta 61,6% no treino, enquanto dizer “outra variedade” para cada vinho acerta 60,0%. O ganho é mínimo, e no teste some. A SVM linear do lab não prevê a variedade 2 em lugar nenhum e fica com 60,4%, a proporção das outras variedades entre os 53 vinhos de teste. Vamos acrescentar a coluna x², o quadrado dos flavonoides padronizados. Os vinhos das duas pontas do eixo têm x² grande; os do meio, pequeno. O mesmo modelo linear agora traça uma reta no plano (x, x²). No eixo dos flavonoides isso são dois limiares, um intervalo de 1,11 a 2,82. A acurácia sobe para 77,4%. O modelo não mudou; mudou o que ele recebe.
Mais atributos não quer dizer melhor, porém. O kNN (k = 5) com 13 medidas químicas reconhece 98,1% dos vinhos separados. Acrescentamos colunas de ruído puro, números aleatórios na mesma escala. Com 200 colunas assim, a acurácia cai para 77,4%. Cada coluna de ruído pesa na distância tanto quanto uma medida real, então os vinhos “mais próximos” deixam de ser parecidos. É a maldição da dimensionalidade: em muitas dimensões, todos os pontos ficam quase à mesma distância uns dos outros.
Jak to policzono
- Vinhos: Wine (Aeberhard e Forina, 1992; UCI, licença CC BY 4.0), 178 vinhos, 13 medidas químicas, 3 variedades. Divisão estratificada: 125 vinhos para aprender, 53 para o teste.
- Atributo novo: um modelo linear (uma máquina de vetores de suporte linear, C = 1) sobre os flavonoides padronizados, variedade 2 contra o resto. Flavonoides médios calculados nos 178 vinhos.
- Ruído: kNN com k = 5 sobre as 13 medidas padronizadas e de 0 a 200 colunas de números de uma distribuição normal (média 0, desvio-padrão 1), sorteados com uma semente fixa.
Por que funciona
Um modelo linear divide o espaço com uma reta (com um plano em mais dimensões). Num eixo, uma reta é um ponto: um limiar. A coluna x² acrescenta um segundo eixo. Os vinhos das duas pontas do eixo dos flavonoides ficam no alto da parábola; os do meio, embaixo. Agora uma reta consegue cortar a variedade 2 por cima. Em outras 20 divisões dos vinhos, sem x² a SVM linear não prevê nem uma vez a variedade 2, e o melhor limiar único do treino só supera “sempre outra” no teste em 1 de 20. Com x² sempre recorta um intervalo: de 67,9 a 84,9% no teste.
Com o ruído é o contrário. A distância no kNN é uma soma de diferenças ao quadrado de todas as colunas. Com 13 medidas, o vinho de treino mais distante está em média 296,5% mais longe que o mais próximo. Com 200 colunas de ruído, só 25,7%. As diferenças no ruído são aleatórias e numerosas, então afogam as 13 diferenças reais. Em 20 sorteios do ruído, 200 colunas dão de 64,2 a 83,0%, sempre abaixo dos 98,1% sem ruído.
Um erro comum
Verdadeiro ou falso: “mais atributos fazem um modelo melhor”. Falso. Um atributo ajuda quando carrega informação num formato que o modelo sabe usar, como x² para a variedade 2. Colunas sem informação atrapalham: 200 colunas de ruído derrubam o kNN de 98,1% para 77,4%. No código abaixo, a acurácia do kNN cai de 0,962 sem ruído para 0,689 com 200 colunas.
Um bom atributo novo costuma nascer de entender o problema: o que deveria importar, e em que formato. Jogar dentro tudo o que der é um convite ao ruído.
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 atributo num bom formato transforma um problema difícil num fácil: x² sobe a acurácia de 60,4% para 77,4%.
- Um modelo linear com colunas novas continua linear; o que muda é o que ele recebe como entrada.
- Colunas sem informação atrapalham: 200 colunas de ruído derrubam o kNN de 98,1% para 77,4%.
- Em muitas dimensões as distâncias se igualam, então os modelos baseados em distância são os que mais perdem.
Mais a fundo: fórmula, código, prática
A matemática
O atributo novo: z = (x − x̄) / s, e o modelo linear recebe (z, z²). A fronteira w₁ · z + w₂ · z² + b = 0 é uma equação do segundo grau em z, então tem até duas raízes: dois limiares no eixo x e um intervalo entre eles.
A distância no kNN: d(a, b)² = Σⱼ (aⱼ − bⱼ)² sobre todas as colunas. Para m colunas de ruído de N(0, 1), cada uma acrescenta em média 2 a d² (a variância da diferença de dois números independentes), qualquer que seja a variedade. Com m grande, a soma do ruído afoga os 13 termos reais, e o contraste (d_max − d_min) / d_min diminui.
No código (Python)
O mesmo experimento no scikit-learn: um modelo linear sobre os flavonoides sem x² e com x² na validação cruzada 10 × 5, depois o kNN com as 13 medidas e um número crescente de colunas de ruído.
import numpy as np
from sklearn.datasets import load_wine
from sklearn.model_selection import cross_val_score, RepeatedStratifiedKFold
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
wine = load_wine(as_frame=True)
x, is2 = wine.data[["flavanoids"]], (wine.target == 1).astype(int)
cv = RepeatedStratifiedKFold(n_splits=5, n_repeats=10, random_state=0)
line = make_pipeline(StandardScaler(), SVC(kernel="linear", C=1))
squared = make_pipeline(StandardScaler(), PolynomialFeatures(2, include_bias=False), StandardScaler(), SVC(kernel="linear", C=1)) # a coluna nova x²
a, b = cross_val_score(line, x, is2, cv=cv), cross_val_score(squared, x, is2, cv=cv)
print(f"cultivar 2 vs the rest from flavanoids, 10 x 5 CV: x only {a.mean():.3f}, x and x^2 {b.mean():.3f}; always 'other' {1 - is2.mean():.3f}")
print(f"x only predicts cultivar 2 for {line.fit(x, is2).predict(x).sum()} of {len(x)} wines; x and x^2 wins in {(b > a).sum()} of 50 folds")
X, y = wine.data.to_numpy(), wine.target.to_numpy()
noise = np.random.default_rng(0).normal(size=(len(X), 200)) # colunas de ruído puro
for m in [0, 10, 50, 200]:
acc = cross_val_score(make_pipeline(StandardScaler(), KNeighborsClassifier(5)), np.hstack([X, noise[:, :m]]), y, cv=cv)
print(f"kNN on 13 measurements + {m} noise columns: {acc.mean():.3f}")
Saída
cultivar 2 vs the rest from flavanoids, 10 x 5 CV: x only 0.601, x and x^2 0.755; always 'other' 0.601
x only predicts cultivar 2 for 0 of 178 wines; x and x^2 wins in 49 of 50 folds
kNN on 13 measurements + 0 noise columns: 0.962
kNN on 13 measurements + 10 noise columns: 0.940
kNN on 13 measurements + 50 noise columns: 0.842
kNN on 13 measurements + 200 noise columns: 0.689
As divisões e o ruído são diferentes dos do lab, então os números também diferem um pouco. A imagem é a mesma: sem x² o modelo não prevê nem uma vez a variedade 2 (0,601, o mesmo que “sempre outra”), com x² chega a 0,755 e vence em 49 de 50 partes de validação. O ruído derruba o kNN de 0,962 para 0,689.
Baixar o notebook (.ipynb). Abra no Jupyter ou envie para o Google Colab; ele baixa sozinho os dados que faltarem.
Para quem pratica
- No scikit-learn:
PolynomialFeatures(2)acrescenta quadrados e produtos de pares de atributos,SplineTransformercurvas suaves,FunctionTransformer(np.log1p)um logaritmo para atributos de cauda longa. Coloque-os emmake_pipeline, para que a validação cruzada veja o caminho inteiro. - Os melhores atributos vêm do conhecimento do problema: uma razão (preço por metro quadrado), uma diferença (dias desde a última compra), uma parte da data (dia da semana). O modelo não vai inventá-los se não receber os ingredientes brutos num bom formato.
- Quando há muitos atributos, escolha-os dentro de cada divisão (
SelectKBestno pipeline) ou use um modelo com regularização (lição 3.4). Escolher atributos com todos os dados antes da validação é vazamento (lição 4.5). - Os métodos de kernel que você vai conhecer com as máquinas de vetores de suporte calculam o resultado como se tivessem acrescentado essas colunas, mas sem construí-las explicitamente.
Isto foi útil?
Obrigado! Isso nos ajuda a melhorar.
Vá mais fundo no Atlas
Verbetes da enciclopédia sobre as ideias desta aula: