Discutimos até agora regressão linear que é um método paramétrico.
Métodos Paramétricos:
Vantagens: fácil de ajustar, porque a estimação se resume a estimar um conjunto de coeficientes. Os coeficientes tem interpretação mais simples e podemos fazer testes estatísticos.
Desvantagem: fazem suposições sobre a forma de \(f(X)\). Se a forma funcional especificada está longe da verdadeira, a predição será ruim.
Métodos Não-Paramétricos:
Em inglês k-Nearest Neighbors (KNN) regression (usaremos essa sigla).
Esse é um método não-paramétrico bastante conhecido em algoritmos de classificação, mas também pode ser usado em algoritmos de regressão.
O "vizinho mais próximo" é definido de acordo com alguma medida de similaridade (por ex: distância Euclidiana, distância de Hamming).

"Diga-me com quem andas que te direi quem és!"
Um dos algoritmos mais simples vistos em machine learning e um dos top 10 em data mining (reconhecimento de padrão).

Classificação: classifica uma nova observação de acordo com a classificação da maioria de seus \(k\) vizinhos mais próximos.
Regressão: Estima o valor de uma nova observação de acordo com a média dos valores de seus \(k\) vizinhos mais próximos.
Considere os dados de treinamento \((x_i, y_i)\) para \(i=1, \ldots, n\) e \(x_i \in \mathbb R^p\), uma nova observação com preditores \(x_0\) e uma medida de distância \(d(x_0,.)\).
Escolhido um valor de \(k\), a regressão por KNN identifica \(k\) observações no dados de treinamento que estão mais próximos a \(x_0\) de acordo com \(d(x_0,.)\), ou seja, para todos os \(x_i\)'s de treinamento, calcula-se todas as distâncias (por exemplo, Euclidiana): \[\qquad \displaystyle d(x_0, x_i) = \sqrt{\sum_{j=1}^p (x_{0j} - x_{ij})^2}.\] Nota: A distância pode ser dominada por algum preditor que esteja numa escala bem maior que os demais. Portanto, é essencial padronizar os preditores!
Ordena as distâncias \(d(x_0, x_i)\) para \(i=1, \ldots, n\) e armazena \(k\) \(y_i\)'s correspondentes às menores distâncias.
Seja \(\mathcal N_k(x_0)\) essa vizinhança que contém os \(k\) vizinhos de \(x_0\).
A estimativa será dada pela média de todas as respostas no treinamento pertencentes a \(N_k(x_0)\): \[\widehat y_0 = \widehat f(x_0) = \frac{1}{k} \sum_{x_i \in \mathcal N_k(x_0)} y_i.\]
Nesse algoritmo não há muito de aprendizagem nos dados de treinamento.
Aqui \(k\) é o parâmetro de ajuste (tuning parameter ou hiperparâmetro).
Veja um exemplo de regressão KNN usando dois preditores em um conjunto com 64 observações (pontos laranja) com \(k=1\) (esquerda) e \(k=9\) (direita).
\(k=1\): interpolação dos dados de treinamento e toma a forma de uma escada.
\(k=9\): toma uma média de 9 observações, então o ajuste se torna mais suave.
Valores pequenos de \(k\):
Valores grandes de \(k\):
Como encontrar o valor ótimo de \(k\)? Validação Cruzada.
Gráficos de \(\widehat f(X)\) por regressão KNN com um preditor com \(k=1\) (esquerda) e \(k=9\) (direita). A linha preta representa a verdadeira \(f(X)\).
Quando que um modelo paramétrico, no caso uma regressão linear, será melhor que um modelo não-paramétrico?
Aqui a linha azul pontilhada (esquerda) representa o ajuste por mínimos quadrados e na direita temos o MSE no conjunto de teste da regressão linear (linha pontilhada) e o MSE de teste para a regressão KNN como função de \(1/k\).
Regressão linear será sempre melhor que KNN nesse caso, já que \(f(X)\) é de fato linear.
Na prática, a relação entre \(X\) e \(Y\) dificilmente é linear. Então, o que acontece quando aumentamos o nível de não-linearidade de \(f(X)\)?
A regressão linear é melhor para valores pequenos de \(k\). Para \(k \leq 4\), KNN apresenta melhor performance.
Relação entre \(X\) e \(Y\) claramente não linear:
Nesse caso, KNN tem melhor desempenho para qualquer valor de \(k\).
Veja que o MSE de teste no KNN muda pouco com a mudança da relação de linear para não-linear. Enquanto que o MSE de teste aumenta significativamente com regressão linear.
Na prática, quando não conhecemos a verdadeira relação entre \(X\) e \(Y\), escolhemos KNN ou regressão linear?
Veja o que acontece com o mesmo exemplo do slide anterior, mas agora adicionando preditores que não estão associados com a resposta (ruído).
Conclusões?
Com poucos preditores, KNN apresenta melhor desempenho se comparado a regressão linear.
Problema comum em KNN: desempenho diminui à medida que aumenta a dimensionalidade dos dados. Isso vem do fato que em altas dimenções, há uma redução no número de efetivo de observações.
Pense no que acontece com \(n=100\) quando:
De maneira geral, métodos paramétricos tendem a ter melhor desempenho quando existe um número pequeno de observações por preditor.
Métodos paramétricos também são preferíveis pela sua interpretabilidade.
library(ElemStatLearn) data(prostate)
prostateResposta lpsa: nível de um antígeno específico de câncer de próstata.
Considere inicialmente apenas um preditor: lcavol (log do volume do câncer).

prostateSeparando os dados de treinamento e teste:
library(dplyr) prost.tr = prostate %>% filter(train) # train observations prost.te = prostate %>% filter(!train) # test observations
Vamos ajustar uma regressão linear simples:
prost.linreg = lm(lpsa ~ lcavol, data = prost.tr) summary(prost.linreg)$coef
## Estimate Std. Error t value Pr(>|t|) ## (Intercept) 1.5163048 0.14772483 10.264387 3.123765e-15 ## lcavol 0.7126351 0.08199036 8.691694 1.733134e-12
prostate
prostateMSE para os dados de treinamento:
library(ModelMetrics) pred.tr = predict(prost.linreg) (lm.train.mse <- mse(prost.tr$lpsa, pred.tr))
## [1] 0.6646057
MSE para os dados de teste:
pred.te = predict(prost.linreg, newdata = prost.te) (lm.test.mse <- mse(prost.te$lpsa, pred.te))
## [1] 0.4797387
prostate: KNNAjustando uma regressão KNN com \(k=1, 5 e 15\).
Como aqui temos apenas uma covariável, não é necessário padronizar.
Para os dados de treinamento, usando o pacote FNN:
library(dplyr) library(FNN) Xtrain = prost.tr %>% select(lcavol) # Ajustando KNN e calculando o MSE_Tr para k=1 TrainKnny1 <- knn.reg(train = Xtrain, test = Xtrain, y = prost.tr$lpsa, k=1) knn1.train.mse <- mse(prost.tr$lpsa, TrainKnny1$pred)
prostate: KNNPredição para os dados de teste, calculando as distâncias em relação aos dados de treinamento.
Xtest = prost.te %>% select(lcavol) TestKnny1 <- knn.reg(train = Xtrain, test = Xtest, y = prost.tr$lpsa, k=1) knn1.test.mse <- mse(prost.te$lpsa, TestKnny1$pred)
prostate: comparando diferentes métodoslibrary(printr)
res <- cbind(c("LM", "KNN 15", "KNN5", "KNN 1"),
round(c(lm.train.mse, knn15.train.mse, knn5.train.mse, knn1.train.mse), 2),
round(c(lm.test.mse, knn15.test.mse, knn5.test.mse, knn1.test.mse), 2))
rbind(c("Método", "MSE-Treino", "MSE-Teste"), res)
| Método | MSE-Treino | MSE-Teste |
| LM | 0.66 | 0.48 |
| KNN 15 | 0.69 | 0.52 |
| KNN5 | 0.55 | 0.48 |
| KNN 1 | 0.01 | 0.83 |
prostate| k | MSE-Train | MSE-Test |
|---|---|---|
| 1 | 0.0087720 | 0.8303316 |
| 4 | 0.5141037 | 0.4176132 |
| 7 | 0.6181437 | 0.4427197 |
| 9 | 0.6680769 | 0.4781785 |
| 12 | 0.7100130 | 0.4959484 |
| 14 | 0.6904456 | 0.5087311 |
| 17 | 0.7402980 | 0.5448028 |
| 20 | 0.7790462 | 0.5474455 |
| 45 | 0.9920038 | 0.7221205 |
| 48 | 1.0381039 | 0.7585145 |
| 50 | 1.0563493 | 0.7720519 |
prostate
Slides produzidos pelas professoras:
Samara Kiihl
Tatiana Benaglia
Algumas figuras foram retiradas dos livros ELS e ISLR com permissão dos autores.