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