Chapter 5 Modelos Supervisionados I - Knn
Vamos fazer passo a passo um knn? Vamos empregar aqui o dataset iris para que você tenha um roteiro passo a passo de como aplicar um modelo de aprendizado knn (k-vizinhos mais próximos) para classificar as instâncias de iris.
5.1 Passo 0. Inclua as bibliotecas
Cada modelo emprega normalmente um conjunto diferente de bibliotecas.
library(class)
help(knn)
## starting httpd help server ... done
5.2 Passo 1. Explore o seu dataset
Caso a caso você faz um EDA dos dados empregando seleções de dados, gráficos etc.
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
nrow(iris)
## [1] 150
table(iris$Species) # mostra a quantidade de registros de cada Specie
##
## setosa versicolor virginica
## 50 50 50
barplot(table(iris$Species))
5.3 Passo 2. Preparando os dados
Veremos mais sobre isso adiante. Os dados podem requerer algum tipo de preparação antes de serem empregados no modelo como eliminar dados faltantes, atributos que não são empregadas no aprendizado (saberia dizer quais?)etc. Para o caso do iris não será necessário aqui nenhuma preparação.
my_iris = na.omit(iris) # elimina as linhas com valores NA
# no caso pode ser omitido pois não existem valores NA em iris, mas fica aqui um roteiro geral para outros datasets.
5.4 Passo 3 . Conjuntos de Treinamento e Teste
Aqui você vai separar 1/3 dos dados para teste e os 2/3 restantes para o treinamento. Às vezes pediremos para você empregar .3 dos dados, então fique atento. Para garantir que não teremos dados com viés a seleção deve ser aleatória e empregamos a função sample( )
. Veja também o emprego do seed()
fixando, neste caso a semente de geração aleatória.
set.seed(1985) # garante a mesma amostra a cada execução e a compatibilidade com os exercícios
RNGversion('3.5.1')
L = sample( 1: nrow(iris), round(nrow(iris)/3) )
print(L)
## [1] 132 99 125 15 4 119 19 101 77 60 109 17 115 49 92 78 137 96 142
## [20] 80 134 100 37 93 13 67 11 123 66 128 120 85 149 47 29 63 105 25
## [39] 112 68 139 72 45 87 43 21 144 56 8 117
1: nrow(iris)
define o intervalo de valores 1:150
do qual queremos selecionar 1/3 dos dados aleatoriamente.
Nosso conjunto de testes poderá ser então:
test = iris[ L , -5 ] # Veja que o test exclui a classe Species que é a classificação desejada
O conjunto de treinamento será formado pelas demais linhas ou o complemento (-L).
train = iris[ -L , -5 ] # Para o knn a classe Species também é eliminada do conjunto. Species irá compor o parâmetro cl da função knn.
A função knn, requer as classes (Species
) de todos elementos do treinamento em um atributo a parte como a seguir:
cl = iris[ -L , 5 ] # Este é somente o atributo 5 (Species) do mesmos registros do conjunto de treinamento (-L)
5.5 Passo 4. Aplicando o modelo knn
A função knn
pode ser agora aplicada, por exemplo para o valor de k=3, do seguinte modo
fit = knn(train, test, cl, k = 3)
print(fit)
## [1] virginica versicolor virginica setosa setosa virginica
## [7] setosa virginica versicolor versicolor virginica setosa
## [13] virginica setosa versicolor virginica virginica versicolor
## [19] virginica versicolor versicolor versicolor setosa versicolor
## [25] setosa versicolor setosa virginica versicolor virginica
## [31] versicolor versicolor virginica setosa setosa versicolor
## [37] virginica setosa virginica versicolor virginica versicolor
## [43] setosa versicolor setosa setosa virginica versicolor
## [49] setosa virginica
## Levels: setosa versicolor virginica
nota: O parâmetro cl
, de classes, deve ser do tipo factor na função knn. No caso para o dataset iris esse já é o formato de Species
. Caso contrário, aplique s.factor(cl)
para converter sua variável.
Note que fit retorna a classificação dos L registros de teste pelo algoritmo de aprendizado knn para k=3.
5.6 Passo 5. Avalie o modelo
Você pode então avaliar o resultado do seu modelo comparando as respostas obtidas para o L registros e a classe que consta no dataset original (as respostas).
Você não precisa dos comandos abaixo para avaliar o modelo, mas ele ajudará você a ver esses valores lado a lado e entender melhor o que está acontecendo
cbind(iris[L,],fit,iris[L,]$Species==fit)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species fit
## 132 7.9 3.8 6.4 2.0 virginica virginica
## 99 5.1 2.5 3.0 1.1 versicolor versicolor
## 125 6.7 3.3 5.7 2.1 virginica virginica
## 15 5.8 4.0 1.2 0.2 setosa setosa
## 4 4.6 3.1 1.5 0.2 setosa setosa
## 119 7.7 2.6 6.9 2.3 virginica virginica
## 19 5.7 3.8 1.7 0.3 setosa setosa
## 101 6.3 3.3 6.0 2.5 virginica virginica
## 77 6.8 2.8 4.8 1.4 versicolor versicolor
## 60 5.2 2.7 3.9 1.4 versicolor versicolor
## 109 6.7 2.5 5.8 1.8 virginica virginica
## 17 5.4 3.9 1.3 0.4 setosa setosa
## 115 5.8 2.8 5.1 2.4 virginica virginica
## 49 5.3 3.7 1.5 0.2 setosa setosa
## 92 6.1 3.0 4.6 1.4 versicolor versicolor
## 78 6.7 3.0 5.0 1.7 versicolor virginica
## 137 6.3 3.4 5.6 2.4 virginica virginica
## 96 5.7 3.0 4.2 1.2 versicolor versicolor
## 142 6.9 3.1 5.1 2.3 virginica virginica
## 80 5.7 2.6 3.5 1.0 versicolor versicolor
## 134 6.3 2.8 5.1 1.5 virginica versicolor
## 100 5.7 2.8 4.1 1.3 versicolor versicolor
## 37 5.5 3.5 1.3 0.2 setosa setosa
## 93 5.8 2.6 4.0 1.2 versicolor versicolor
## 13 4.8 3.0 1.4 0.1 setosa setosa
## 67 5.6 3.0 4.5 1.5 versicolor versicolor
## 11 5.4 3.7 1.5 0.2 setosa setosa
## 123 7.7 2.8 6.7 2.0 virginica virginica
## 66 6.7 3.1 4.4 1.4 versicolor versicolor
## 128 6.1 3.0 4.9 1.8 virginica virginica
## 120 6.0 2.2 5.0 1.5 virginica versicolor
## 85 5.4 3.0 4.5 1.5 versicolor versicolor
## 149 6.2 3.4 5.4 2.3 virginica virginica
## 47 5.1 3.8 1.6 0.2 setosa setosa
## 29 5.2 3.4 1.4 0.2 setosa setosa
## 63 6.0 2.2 4.0 1.0 versicolor versicolor
## 105 6.5 3.0 5.8 2.2 virginica virginica
## 25 4.8 3.4 1.9 0.2 setosa setosa
## 112 6.4 2.7 5.3 1.9 virginica virginica
## 68 5.8 2.7 4.1 1.0 versicolor versicolor
## 139 6.0 3.0 4.8 1.8 virginica virginica
## 72 6.1 2.8 4.0 1.3 versicolor versicolor
## 45 5.1 3.8 1.9 0.4 setosa setosa
## 87 6.7 3.1 4.7 1.5 versicolor versicolor
## 43 4.4 3.2 1.3 0.2 setosa setosa
## 21 5.4 3.4 1.7 0.2 setosa setosa
## 144 6.8 3.2 5.9 2.3 virginica virginica
## 56 5.7 2.8 4.5 1.3 versicolor versicolor
## 8 5.0 3.4 1.5 0.2 setosa setosa
## 117 6.5 3.0 5.5 1.8 virginica virginica
## iris[L, ]$Species == fit
## 132 TRUE
## 99 TRUE
## 125 TRUE
## 15 TRUE
## 4 TRUE
## 119 TRUE
## 19 TRUE
## 101 TRUE
## 77 TRUE
## 60 TRUE
## 109 TRUE
## 17 TRUE
## 115 TRUE
## 49 TRUE
## 92 TRUE
## 78 FALSE
## 137 TRUE
## 96 TRUE
## 142 TRUE
## 80 TRUE
## 134 FALSE
## 100 TRUE
## 37 TRUE
## 93 TRUE
## 13 TRUE
## 67 TRUE
## 11 TRUE
## 123 TRUE
## 66 TRUE
## 128 TRUE
## 120 FALSE
## 85 TRUE
## 149 TRUE
## 47 TRUE
## 29 TRUE
## 63 TRUE
## 105 TRUE
## 25 TRUE
## 112 TRUE
## 68 TRUE
## 139 TRUE
## 72 TRUE
## 45 TRUE
## 87 TRUE
## 43 TRUE
## 21 TRUE
## 144 TRUE
## 56 TRUE
## 8 TRUE
## 117 TRUE
Podemos contar os acertos (TRUE) e erros (FALSE) e calcular o percentual de acerto do modelo. Você pode obter isso através da matriz de confusão:
M = table(fit,iris[L,]$Species)
print(M)
##
## fit setosa versicolor virginica
## setosa 15 0 0
## versicolor 0 16 2
## virginica 0 1 16
Ela compara os resultados das classes obtida pelo modelo e as classes do conjunto original. As quantidades de acerto aparecem na diagonal e os valores não diagonais são as classificações erradas do modelo (lembre-se, é um modelo probabilístico).
cat( "Acuracidade do modelo: ", sum(diag(M))/sum(M) *100, " %" )
## Acuracidade do modelo: 94 %
5.7 Knn. Modelo completo
Segue o código completo do modelo.
library(class)
set.seed(1985)
RNGversion('3.5.1')
head(iris)
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
## 6 5.4 3.9 1.7 0.4 setosa
L = sample(1:nrow(iris),round(nrow(iris)/3))
train = iris[-L,1:4]
test = iris[L,1:4]
cl = iris[-L,5]
fit = knn(train, test, cl, k = 3)
print(fit)
## [1] virginica versicolor virginica setosa setosa virginica
## [7] setosa virginica versicolor versicolor virginica setosa
## [13] virginica setosa versicolor virginica virginica versicolor
## [19] virginica versicolor versicolor versicolor setosa versicolor
## [25] setosa versicolor setosa virginica versicolor virginica
## [31] versicolor versicolor virginica setosa setosa versicolor
## [37] virginica setosa virginica versicolor virginica versicolor
## [43] setosa versicolor setosa setosa virginica versicolor
## [49] setosa virginica
## Levels: setosa versicolor virginica
print(cbind(iris[L,],fit,iris[L,]$Species==fit))
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species fit
## 132 7.9 3.8 6.4 2.0 virginica virginica
## 99 5.1 2.5 3.0 1.1 versicolor versicolor
## 125 6.7 3.3 5.7 2.1 virginica virginica
## 15 5.8 4.0 1.2 0.2 setosa setosa
## 4 4.6 3.1 1.5 0.2 setosa setosa
## 119 7.7 2.6 6.9 2.3 virginica virginica
## 19 5.7 3.8 1.7 0.3 setosa setosa
## 101 6.3 3.3 6.0 2.5 virginica virginica
## 77 6.8 2.8 4.8 1.4 versicolor versicolor
## 60 5.2 2.7 3.9 1.4 versicolor versicolor
## 109 6.7 2.5 5.8 1.8 virginica virginica
## 17 5.4 3.9 1.3 0.4 setosa setosa
## 115 5.8 2.8 5.1 2.4 virginica virginica
## 49 5.3 3.7 1.5 0.2 setosa setosa
## 92 6.1 3.0 4.6 1.4 versicolor versicolor
## 78 6.7 3.0 5.0 1.7 versicolor virginica
## 137 6.3 3.4 5.6 2.4 virginica virginica
## 96 5.7 3.0 4.2 1.2 versicolor versicolor
## 142 6.9 3.1 5.1 2.3 virginica virginica
## 80 5.7 2.6 3.5 1.0 versicolor versicolor
## 134 6.3 2.8 5.1 1.5 virginica versicolor
## 100 5.7 2.8 4.1 1.3 versicolor versicolor
## 37 5.5 3.5 1.3 0.2 setosa setosa
## 93 5.8 2.6 4.0 1.2 versicolor versicolor
## 13 4.8 3.0 1.4 0.1 setosa setosa
## 67 5.6 3.0 4.5 1.5 versicolor versicolor
## 11 5.4 3.7 1.5 0.2 setosa setosa
## 123 7.7 2.8 6.7 2.0 virginica virginica
## 66 6.7 3.1 4.4 1.4 versicolor versicolor
## 128 6.1 3.0 4.9 1.8 virginica virginica
## 120 6.0 2.2 5.0 1.5 virginica versicolor
## 85 5.4 3.0 4.5 1.5 versicolor versicolor
## 149 6.2 3.4 5.4 2.3 virginica virginica
## 47 5.1 3.8 1.6 0.2 setosa setosa
## 29 5.2 3.4 1.4 0.2 setosa setosa
## 63 6.0 2.2 4.0 1.0 versicolor versicolor
## 105 6.5 3.0 5.8 2.2 virginica virginica
## 25 4.8 3.4 1.9 0.2 setosa setosa
## 112 6.4 2.7 5.3 1.9 virginica virginica
## 68 5.8 2.7 4.1 1.0 versicolor versicolor
## 139 6.0 3.0 4.8 1.8 virginica virginica
## 72 6.1 2.8 4.0 1.3 versicolor versicolor
## 45 5.1 3.8 1.9 0.4 setosa setosa
## 87 6.7 3.1 4.7 1.5 versicolor versicolor
## 43 4.4 3.2 1.3 0.2 setosa setosa
## 21 5.4 3.4 1.7 0.2 setosa setosa
## 144 6.8 3.2 5.9 2.3 virginica virginica
## 56 5.7 2.8 4.5 1.3 versicolor versicolor
## 8 5.0 3.4 1.5 0.2 setosa setosa
## 117 6.5 3.0 5.5 1.8 virginica virginica
## iris[L, ]$Species == fit
## 132 TRUE
## 99 TRUE
## 125 TRUE
## 15 TRUE
## 4 TRUE
## 119 TRUE
## 19 TRUE
## 101 TRUE
## 77 TRUE
## 60 TRUE
## 109 TRUE
## 17 TRUE
## 115 TRUE
## 49 TRUE
## 92 TRUE
## 78 FALSE
## 137 TRUE
## 96 TRUE
## 142 TRUE
## 80 TRUE
## 134 FALSE
## 100 TRUE
## 37 TRUE
## 93 TRUE
## 13 TRUE
## 67 TRUE
## 11 TRUE
## 123 TRUE
## 66 TRUE
## 128 TRUE
## 120 FALSE
## 85 TRUE
## 149 TRUE
## 47 TRUE
## 29 TRUE
## 63 TRUE
## 105 TRUE
## 25 TRUE
## 112 TRUE
## 68 TRUE
## 139 TRUE
## 72 TRUE
## 45 TRUE
## 87 TRUE
## 43 TRUE
## 21 TRUE
## 144 TRUE
## 56 TRUE
## 8 TRUE
## 117 TRUE
c_matrix = table(fit,iris[L,5])
print(c_matrix)
##
## fit setosa versicolor virginica
## setosa 15 0 0
## versicolor 0 16 2
## virginica 0 1 16
cat('Accuracy: ', sum(diag(c_matrix))/sum(c_matrix)*100, ' %')
## Accuracy: 94 %
5.8 Exercício.
Faça agora o exercício do Moodle explorando esse código.
Somente uma dica caso queira ordenar os elementos. Mas não é necessário empregar.
x = cbind(test,fit,iris[L,5])
x$index = as.numeric(row.names(x))
x[order(x$index), ]
## Sepal.Length Sepal.Width Petal.Length Petal.Width fit iris[L, 5]
## 4 4.6 3.1 1.5 0.2 setosa setosa
## 8 5.0 3.4 1.5 0.2 setosa setosa
## 11 5.4 3.7 1.5 0.2 setosa setosa
## 13 4.8 3.0 1.4 0.1 setosa setosa
## 15 5.8 4.0 1.2 0.2 setosa setosa
## 17 5.4 3.9 1.3 0.4 setosa setosa
## 19 5.7 3.8 1.7 0.3 setosa setosa
## 21 5.4 3.4 1.7 0.2 setosa setosa
## 25 4.8 3.4 1.9 0.2 setosa setosa
## 29 5.2 3.4 1.4 0.2 setosa setosa
## 37 5.5 3.5 1.3 0.2 setosa setosa
## 43 4.4 3.2 1.3 0.2 setosa setosa
## 45 5.1 3.8 1.9 0.4 setosa setosa
## 47 5.1 3.8 1.6 0.2 setosa setosa
## 49 5.3 3.7 1.5 0.2 setosa setosa
## 56 5.7 2.8 4.5 1.3 versicolor versicolor
## 60 5.2 2.7 3.9 1.4 versicolor versicolor
## 63 6.0 2.2 4.0 1.0 versicolor versicolor
## 66 6.7 3.1 4.4 1.4 versicolor versicolor
## 67 5.6 3.0 4.5 1.5 versicolor versicolor
## 68 5.8 2.7 4.1 1.0 versicolor versicolor
## 72 6.1 2.8 4.0 1.3 versicolor versicolor
## 77 6.8 2.8 4.8 1.4 versicolor versicolor
## 78 6.7 3.0 5.0 1.7 virginica versicolor
## 80 5.7 2.6 3.5 1.0 versicolor versicolor
## 85 5.4 3.0 4.5 1.5 versicolor versicolor
## 87 6.7 3.1 4.7 1.5 versicolor versicolor
## 92 6.1 3.0 4.6 1.4 versicolor versicolor
## 93 5.8 2.6 4.0 1.2 versicolor versicolor
## 96 5.7 3.0 4.2 1.2 versicolor versicolor
## 99 5.1 2.5 3.0 1.1 versicolor versicolor
## 100 5.7 2.8 4.1 1.3 versicolor versicolor
## 101 6.3 3.3 6.0 2.5 virginica virginica
## 105 6.5 3.0 5.8 2.2 virginica virginica
## 109 6.7 2.5 5.8 1.8 virginica virginica
## 112 6.4 2.7 5.3 1.9 virginica virginica
## 115 5.8 2.8 5.1 2.4 virginica virginica
## 117 6.5 3.0 5.5 1.8 virginica virginica
## 119 7.7 2.6 6.9 2.3 virginica virginica
## 120 6.0 2.2 5.0 1.5 versicolor virginica
## 123 7.7 2.8 6.7 2.0 virginica virginica
## 125 6.7 3.3 5.7 2.1 virginica virginica
## 128 6.1 3.0 4.9 1.8 virginica virginica
## 132 7.9 3.8 6.4 2.0 virginica virginica
## 134 6.3 2.8 5.1 1.5 versicolor virginica
## 137 6.3 3.4 5.6 2.4 virginica virginica
## 139 6.0 3.0 4.8 1.8 virginica virginica
## 142 6.9 3.1 5.1 2.3 virginica virginica
## 144 6.8 3.2 5.9 2.3 virginica virginica
## 149 6.2 3.4 5.4 2.3 virginica virginica
## index
## 4 4
## 8 8
## 11 11
## 13 13
## 15 15
## 17 17
## 19 19
## 21 21
## 25 25
## 29 29
## 37 37
## 43 43
## 45 45
## 47 47
## 49 49
## 56 56
## 60 60
## 63 63
## 66 66
## 67 67
## 68 68
## 72 72
## 77 77
## 78 78
## 80 80
## 85 85
## 87 87
## 92 92
## 93 93
## 96 96
## 99 99
## 100 100
## 101 101
## 105 105
## 109 109
## 112 112
## 115 115
## 117 117
## 119 119
## 120 120
## 123 123
## 125 125
## 128 128
## 132 132
## 134 134
## 137 137
## 139 139
## 142 142
## 144 144
## 149 149
5.9 Laboratório.
Faça agora os exercícios do Moodle explorando o dataset kyphosis
.
library(class) # knn
library(rpart) # dataset kyphosis
set.seed(1984) # garante a uniformidade das respostas!
RNGversion('3.5.1')
#
# Explorando o data set
head(kyphosis)
## Kyphosis Age Number Start
## 1 absent 71 3 5
## 2 absent 158 3 14
## 3 present 128 4 5
## 4 absent 2 5 1
## 5 absent 1 4 15
## 6 absent 1 2 16