Machine Learning · Insper

k-Vizinhos Mais Próximos

Abordagem fundamental

Como o k-NN decide e o que ele precisa para decidir bem

Duas maneiras de usar os dados de treino

Regressão logística

  • lê o treino inteiro
  • resume tudo em \(d + 1\) números
  • traça uma reta
  • descarta as linhas

k-NN

  • guarda todas as linhas
  • para um ponto novo, acha as \(k\) mais parecidas
  • elas votam
  • a fronteira tem a forma que os dados sugerirem
O "modelo" do k-NN são os próprios dados de treino.

O caminho desta parte

  1. Os vizinhos votamdistância a cada linha; os k mais próximos votam; o fit só guarda
  2. Escalonar antesas unidades decidem a distância; o escalonador entra num pipeline
  3. Escolher k, testar uma vezviés e variância; a validação escolhe, o teste confirma
Cada etapa responde a uma pergunta: como o k-NN decide? → o que torna "perto" justo? → quantos vizinhos devem votar?
Etapa 1 · Como o k-NN decide?

Um problema: ele vai gostar da série?

  • Um streaming vai recomendar uma série que mistura ação e documentário.
  • Para 10 assinantes que já a viram, sabemos as horas por semana de filmes de ação e de documentários e se gostaram.
  • Um assinante novo assiste 4 h de ação e 4 h de documentários.

"Parecido" vira um número: a distância euclidiana até o assinante novo.

\[ d = \sqrt{(\text{ação} - 4)^2 + (\text{doc} - 4)^2} \]

Primeiro: medir a distância até cada um

posiçãonomeaçãodocgostou?\(d\)
1Ana54sim1,000
2Bruno25não2,236
3Carla66não2,828
4Davi47sim3,000
5Elisa73sim3,162
6–10Felipe, Gabi, Hugo, Iara, João: de 3,606 a 5,831

Ana: \(\sqrt{(5-4)^2 + (4-4)^2} = 1\). Ordene do mais perto ao mais longe.

Depois: os \(k\) mais próximos votam

Os 10 assinantes e os círculos com os 1, 3 e 5 vizinhos mais próximos do assinante novo
  • \(k = 1\): Ana → gostou (1/1)
  • \(k = 3\): 1 sim × 2 não → não gostou (1/3)
  • \(k = 5\): 3 sim × 2 não → gostou (3/5)
Mesmos dados, mesma consulta, três respostas. O \(k\) é a principal decisão que o k-NN deixa para você.

O algoritmo em três passos

  1. calcule a distância da consulta \(x\) a todo ponto de treino;
  2. fique com os \(k\) mais próximos, a vizinhança \(N_k(x)\);
  3. preveja a classe mais frequente entre eles.

A "probabilidade" da classe \(c\) é só a fração de vizinhos nela:

\[ \hat{p}_c(x) = \frac{1}{k} \sum_{i \in N_k(x)} \mathbb{1}[y_i = c] \]

No exemplo: predict_proba dá 1,000, 0,333 e 0,600 para \(k\) = 1, 3 e 5.

O que o fit guarda

regressão logísticak-NN
o fit produz\(d + 1\) númerosuma cópia da tabela de treino
fronteirauma reta (hiperplano)qualquer forma
custo do fitotimização iterativaquase nenhum: guardar
custo de prever\(d\) multiplicações\(n\) distâncias
explica comum coeficiente por atributo"estes são os casos mais parecidos"
Aprendiz preguiçoso: o trabalho de verdade fica para a hora de prever.
Etapa 2 · O que torna "perto" justo?

As unidades decidem a distância

Cliente novo de uma agência: R$ 5.000 por mês, 25 anos. Ele compra o pacote de mochilão?

clienterendaidadecomprou?\(d\) bruta\(d\) padronizada
Rita5.20061não203,22,57
Otávio5.70026sim700,00,32
  • Bruta: \(\sqrt{200^2 + 36^2} = 203{,}2\). Os 36 anos somam só 3,2, porque um ano pesa o mesmo que um real. 1-NN: Rita → não.
  • Padronizada (cada atributo ÷ seu desvio padrão): o mais próximo é Otávio → sim.

O mesmo caso, em figura

Em unidades brutas, o círculo em volta do cliente novo é uma faixa vertical; padronizado, o vizinho mais próximo é o Otávio

Em unidades brutas, um "círculo" de raio 203 é uma faixa de R$ 203 para cada lado que contém todas as idades.

Num conjunto real: os vinhos

Desvio padrão dos atributos do wine:

proline314,91
magnesium14,28
alcalinity_of_ash3,34
color_intensity2,32

Acurácia de teste do 5-NN (54 vinhos):

sem escalonar0,722
StandardScaler0,963
MinMaxScaler0,963
Sem escalonar, o 5-NN classifica vinhos por uma coluna entre 13: a prolina.

Regra: escalone, sempre dentro de um pipeline


from sklearn.neighbors import KNeighborsClassifier
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler

knn = make_pipeline(StandardScaler(),
                    KNeighborsClassifier(n_neighbors=5))
knn.fit(X_train, y_train)
  
  • o escalonador aprende médias e desvios só nas linhas de treino;
  • validação e teste recebem a mesma transformação, sem reajuste;
  • exceção: atributos que já compartilham uma unidade (os pixels do lab avançado).
Etapa 3 · Quantos vizinhos devem votar?

O \(k\) controla a complexidade

Regiões de decisão do k-NN nas luas para k = 1, 15 e 451

\(k = 1\): ilhas em volta de cada ponto (treino 100%, validação 85,0%) · \(k = 15\): segue as luas (89,5%) · \(k = 451\): quase uma reta (76,5%)

\(k\) pequeno = modelo complexo (variância alta) · \(k\) grande = modelo simples (viés alto)

Escolher \(k\) na validação

Acurácia de treino e de validação em função de k
  • Treino 100% em \(k = 1\) é por construção: cada ponto é o seu próprio vizinho.
  • Platô: de \(k = 7\) a ~140, a validação fica entre 88,5% e 91,0%.
  • \(k\) grande: treino e validação caem juntos → simples demais.

O protocolo: cada parte tem um papel

treino · 600

são as linhas que o k-NN guarda e que votam

validação · 200

escolhe o \(k\)

\(k = 73\)
validação 91,0%

teste · 200

medido uma vez, no fim, após reajustar em treino + validação

90,0%
O teste fica um ponto abaixo: \(k = 73\) foi escolhido porque foi bem naquelas 200 linhas, então parte dos 91,0% é sorte. Escolher \(k\) no teste destruiria essa honestidade.

Simulador: o voto dos vizinhos

Preveja. O ★ está na fronteira. Percorra o \(k\) de 1 a 25 sem movê-lo: a classe dele fica a mesma? Depois arraste-o pela sobreposição: qual \(k\) oscila mais?

Resumo: a receita do k-NN

  1. Pipeline com escalonador + k-NN.
  2. Divida antes de olhar: treino, validação, teste.
  3. Varra \(k\) ímpar na validação (com duas classes, \(k\) ímpar não empata).
  4. Reajuste em treino + validação e meça o teste uma única vez.
Próximo: o lab fundamental, com vinhos.
Lab fundamental · cerca de 35 min, em duplas

Vinhos: passos 1 a 5

  • Abra o notebook no Colab: nada para baixar. Salve uma cópia no seu Drive para guardar as respostas.
  • Em cada passo, responda o Preveja antes de rodar.
  • Simulações: a unidade da prolina (passo 3) e o voto muda com \(k\) (passo 4).
  • Compare com a saída e a leitura na página da aula.

Ritmo: passos 1 a 3 em 15 min; passos 4 e 5 em 20 min.