Sabatina,

Banco de dados


data(iris)

Medidas em centímetros do comprimento e largura da sépala e pétala, respectivamente, de 50 flores de três espécies de iris. As espécies são Iris setosa, versicolor e virginica

summary(iris)
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.300   Min.   :2.000   Min.   :1.000   Min.   :0.100   setosa    :50  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:50  
 Median :5.800   Median :3.000   Median :4.350   Median :1.300   virginica :50  
 Mean   :5.843   Mean   :3.057   Mean   :3.758   Mean   :1.199                  
 3rd Qu.:6.400   3rd Qu.:3.300   3rd Qu.:5.100   3rd Qu.:1.800                  
 Max.   :7.900   Max.   :4.400   Max.   :6.900   Max.   :2.500                  

Base de treino:

linhas <- matrix(c(0, 50, 100)
                 , ncol = 3
                 , nrow = 30
                 , byrow = TRUE) + replicate(3, sample(1:50, 30))

iris.tr <- iris[linhas, ]

summary(iris.tr)
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.300   Min.   :2.000   Min.   :1.100   Min.   :0.100   setosa    :30  
 1st Qu.:5.100   1st Qu.:2.800   1st Qu.:1.600   1st Qu.:0.300   versicolor:30  
 Median :5.800   Median :3.000   Median :4.400   Median :1.300   virginica :30  
 Mean   :5.869   Mean   :3.044   Mean   :3.782   Mean   :1.216                  
 3rd Qu.:6.575   3rd Qu.:3.200   3rd Qu.:5.200   3rd Qu.:1.800                  
 Max.   :7.700   Max.   :4.200   Max.   :6.900   Max.   :2.500                  

Base de teste:

iris.te <- iris[-linhas, ]

summary(iris.te)
  Sepal.Length    Sepal.Width     Petal.Length    Petal.Width          Species  
 Min.   :4.600   Min.   :2.200   Min.   :1.000   Min.   :0.100   setosa    :20  
 1st Qu.:5.175   1st Qu.:2.700   1st Qu.:1.500   1st Qu.:0.375   versicolor:20  
 Median :5.700   Median :3.000   Median :4.200   Median :1.300   virginica :20  
 Mean   :5.805   Mean   :3.077   Mean   :3.722   Mean   :1.175                  
 3rd Qu.:6.200   3rd Qu.:3.400   3rd Qu.:5.025   3rd Qu.:1.800                  
 Max.   :7.900   Max.   :4.400   Max.   :6.700   Max.   :2.500                  

SVM Kernel


library(e1071)

Linear


\[ K(x_{i}, x_{j}) = \left \langle x_{i}, x_{j} \right \rangle \]


svm_l <- svm(Species ~ ., iris.tr
             , kernel = "linear")
summary(svm_l)

Call:
svm(formula = Species ~ ., data = iris.tr, kernel = "linear")


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  linear 
       cost:  1 
      gamma:  0.25 

Number of Support Vectors:  21

 ( 2 10 9 )


Number of Classes:  3 

Levels: 
 setosa versicolor virginica

Como o classificador se saiu?

tr.svm_l <- predict(svm_l, iris.tr)

table(tr.svm_l, iris.tr$Species)
            
tr.svm_l     setosa versicolor virginica
  setosa         30          0         0
  versicolor      0         30         1
  virginica       0          0        29

Na base de treino ele se saiu muito bem, só errou uma classificação. A flor é da espécie virginica mas foi classificada como versicolor.


E na base de teste?

te.svm_l <- predict(svm_l, iris.te)

table(te.svm_l, iris.te$Species)
            
te.svm_l     setosa versicolor virginica
  setosa         20          0         0
  versicolor      0         19         0
  virginica       0          1        20

Na base de teste ele também se saiu muito bem, cometendo apenas um erro. A flor é da espécie versicolor mas foi classificada como virginica.


E o parâmetro custo, será que encontramos um melhor?

(tune.svm_l <- tune(svm
                    , Species ~ .
                    , data = iris.tr
                    , kernel = "linear"
                    , ranges = list(cost = c(.0001, .001, .01, .1, .5, 1, 2.5, 5, 7.5, 10))))

Parameter tuning of 'svm':

- sampling method: 10-fold cross validation 

- best parameters:
 cost
    1

- best performance: 0.03333333 
summary(tune.svm_l)

Parameter tuning of 'svm':

- sampling method: 10-fold cross validation 

- best parameters:
 cost
    1

- best performance: 0.03333333 

- Detailed performance results:
      cost      error dispersion
1   0.0001 0.64444444 0.28109135
2   0.0010 0.64444444 0.28109135
3   0.0100 0.25555556 0.19633123
4   0.1000 0.04444444 0.05737753
5   0.5000 0.05555556 0.05856070
6   1.0000 0.03333333 0.05367177
7   2.5000 0.04444444 0.05737753
8   5.0000 0.04444444 0.05737753
9   7.5000 0.05555556 0.05856070
10 10.0000 0.05555556 0.05856070

Dez diferentes valores foram propostos, a atual valor, 1, se mostrou melhor (com um menor erro).


Polinomial


\[ K(x_{i}, x_{j}) = (c_{0} + \gamma \left \langle x_{i}, x_{j} \right \rangle)^{d} \]


svm_p <- svm(Species ~ ., iris.tr
             , kernel = "polynomial")
summary(svm_p)

Call:
svm(formula = Species ~ ., data = iris.tr, kernel = "polynomial")


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  polynomial 
       cost:  1 
     degree:  3 
      gamma:  0.25 
     coef.0:  0 

Number of Support Vectors:  37

 ( 5 18 14 )


Number of Classes:  3 

Levels: 
 setosa versicolor virginica

Como o classificador se saiu?

tr.svm_p <- predict(svm_p, iris.tr)

table(tr.svm_p, iris.tr$Species)
            
tr.svm_p     setosa versicolor virginica
  setosa         30          0         0
  versicolor      0         30         7
  virginica       0          0        23

Na base de treino ele errou aqui um pouco mais, classificando 7 flores da espécie virginica como versicolor.


E na base de teste?

te.svm_p <- predict(svm_p, iris.te)

table(te.svm_p, iris.te$Species)
            
te.svm_p     setosa versicolor virginica
  setosa         20          0         0
  versicolor      0         20         9
  virginica       0          0        11

Na base de teste ele também não se saiu muito bem, classificando 9 flores da espécie virginica como versicolor.


Será que encontramos melhores parâmetros?

(tune.svm_p <- tune(svm
                    , Species ~ .
                    , data = iris.tr
                    , kernel = "polynomial"
                    , ranges = list(cost = c(.5, 1, 2.5)
                                    , degree = c(2, 3, 4)
                                    , gamma = c(.01, .25, .5)
                                    , coef0 = c(-1, 0, 1))))

Parameter tuning of 'svm':

- sampling method: 10-fold cross validation 

- best parameters:
 cost degree gamma coef0
    1      3   0.5     0

- best performance: 0.03333333 

Testamos diferentes valores para os parâmetros e apenas um ficou diferente do default, \(\gamma\), que de 0.25 foi para 0.5.


Com essa mudança no parâmetro, como o classificador se sai na base de treino?

svm.tune_p <- svm(Species ~ ., iris.tr
                  , gamma = .5
                  , kernel = "polynomial")

tr.svm.tune_p <- predict(svm.tune_p, iris.tr)

table(tr.svm.tune_p, iris.tr$Species)
             
tr.svm.tune_p setosa versicolor virginica
   setosa         30          0         0
   versicolor      0         30         2
   virginica       0          0        28

Melhor. Antes ele classificava 7 flores de virginica errado, agora apenas 2 flores são classificadas erradas, como versicolor.


E na base de teste, como ele se sai?

te.svm.tune_p <- predict(svm.tune_p, iris.te)

table(te.svm.tune_p, iris.te$Species)
             
te.svm.tune_p setosa versicolor virginica
   setosa         20          0         0
   versicolor      0         20         5
   virginica       0          0        15

Aqui ele também se saiu melhor. Antes 9 flores de virginica eram classificadas erradas, agora 5 flores são classificadas erradas como versicolor.


Radial


\[ K(x_{i}, x_{j}) = {\rm exp} (- \gamma \left \| x_{i}, x_{j} \right \|^{2}) \]


svm_r <- svm(Species ~ ., iris.tr
             , kernel = "radial")
summary(svm_r)

Call:
svm(formula = Species ~ ., data = iris.tr, kernel = "radial")


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  radial 
       cost:  1 
      gamma:  0.25 

Number of Support Vectors:  40

 ( 7 18 15 )


Number of Classes:  3 

Levels: 
 setosa versicolor virginica

Como o classificador se saiu?

tr.svm_r <- predict(svm_r, iris.tr)

table(tr.svm_r, iris.tr$Species)
            
tr.svm_r     setosa versicolor virginica
  setosa         30          0         0
  versicolor      0         30         2
  virginica       0          0        28

Na base de treino ele se saiu bem, classificando apenas 2 flores da espécie virginica como versicolor.


E na base de teste?

te.svm_r <- predict(svm_r, iris.te)

table(te.svm_r, iris.te$Species)
            
te.svm_r     setosa versicolor virginica
  setosa         20          0         0
  versicolor      0         19         1
  virginica       0          1        19

Na base de teste ele também se saiu bem, classificando apenas uma flor da espécie versicolor como virginica e uma flor virginica como versicolor.


Será que encontramos melhores parâmetros?

(tune.svm_r <- tune(svm
                    , Species ~ .
                    , data = iris.tr
                    , kernel = "radial"
                    , ranges = list(cost = c(.5, 1, 2.5, 5)
                                    , gamma = c(.01, .1, .25, .5))))

Parameter tuning of 'svm':

- sampling method: 10-fold cross validation 

- best parameters:
 cost gamma
  2.5   0.1

- best performance: 0.03333333 

Ambos os parâmetros mudaram, o custo aumentou para 2.5 e \(\gamma\) diminuiu para 0.1.


Com essa mudança nos parâmetros, como o classificador se sai na base de treino?

svm.tune_r <- svm(Species ~ ., iris.tr
                  , cost = 2.5
                  , gamma = .1
                  , kernel = "radial")

tr.svm.tune_r <- predict(svm.tune_r, iris.tr)

table(tr.svm.tune_r, iris.tr$Species)
             
tr.svm.tune_r setosa versicolor virginica
   setosa         30          0         0
   versicolor      0         30         2
   virginica       0          0        28

Os mesmos resultados são obtidos.


E na base de teste?

te.svm.tune_r <- predict(svm.tune_r, iris.te)

table(te.svm.tune_r, iris.te$Species)
             
te.svm.tune_r setosa versicolor virginica
   setosa         20          0         0
   versicolor      0         19         1
   virginica       0          1        19

Aqui também os mesmos resultados foram obtidos.


Sigmoid


\[ K(x_{i}, x_{j}) = {\rm tanh} (c_{0} + \gamma \left \langle x_{i}, x_{j} \right \rangle) \]


svm_s <- svm(Species ~ ., iris.tr
             , kernel = "sigmoid")
summary(svm_s)

Call:
svm(formula = Species ~ ., data = iris.tr, kernel = "sigmoid")


Parameters:
   SVM-Type:  C-classification 
 SVM-Kernel:  sigmoid 
       cost:  1 
      gamma:  0.25 
     coef.0:  0 

Number of Support Vectors:  40

 ( 5 19 16 )


Number of Classes:  3 

Levels: 
 setosa versicolor virginica

Como o classificador se saiu?

tr.svm_s <- predict(svm_s, iris.tr)

table(tr.svm_s, iris.tr$Species)
            
tr.svm_s     setosa versicolor virginica
  setosa         30          0         0
  versicolor      0         27         1
  virginica       0          3        29

Na base de treino 4 erros foram cometidos. Uma flor da espécie virginica foi classificada como versicolor, e três da espécie versicolor foram classificadas como virginica.


E na base de teste?

te.svm_s <- predict(svm_s, iris.te)

table(te.svm_s, iris.te$Species)
            
te.svm_s     setosa versicolor virginica
  setosa         20          0         0
  versicolor      0         19         1
  virginica       0          1        19

Aqui os resultados foram muito bons obtidos. Apenas 2 erros ocorrem. Uma flor da espécie versicolor é classificada como virginica, e uma flor virginica é classificada como versicolor.


Será que encontramos melhores parâmetros?

(tune.svm_s <- tune(svm
                    , Species ~ .
                    , data = iris.tr
                    , kernel = "sigmoid"
                    , ranges = list(cost = c(.5, 1, 2.5, 5)
                                    , gamma = c(.01, .1, .25, .5)
                                    , coef0 = c(-1, 0, 1))))

Parameter tuning of 'svm':

- sampling method: 10-fold cross validation 

- best parameters:
 cost gamma coef0
  2.5   0.1    -1

- best performance: 0.03333333 

Todos os parâmetros mudam. O custo aumenta para 2.5, e \(\gamma\) diminuí para 0.1, e \(c\) diminuí para -1.


Como o classificador se sai agora na base de treino?

svm.tune_s <- svm(Species ~ ., iris.tr
                  , cost = 2.5
                  , gamma = .1
                  , coef0 = -1
                  , kernel = "sigmoid")

tr.svm.tune_s <- predict(svm.tune_s, iris.tr)

table(tr.svm.tune_s, iris.tr$Species)
             
tr.svm.tune_s setosa versicolor virginica
   setosa         30          0         0
   versicolor      0         30         3
   virginica       0          0        27

Os resultados melhoram um pouco. Agora 3 erros ocorrem. Três flores virginica são classificadas como versicolor.


E na base de teste?

te.svm.tune_s <- predict(svm.tune_s, iris.te)

table(te.svm.tune_s, iris.te$Species)
             
te.svm.tune_s setosa versicolor virginica
   setosa         20          0         0
   versicolor      0         20         5
   virginica       0          0        15

Aqui os resultados são piores. Antes 2 erros ocorreram, agora 5 erros ocorrem. Cinco flores da espécie virginica são classificadas como versicolor.


Comparando os diferentes tipos de kernel. Qual se saiu melhor?


Observamos que nem sempre os parâmetros default se saem melhor, o que é totalmente lógico e de se esperar.

Bons resultados nas bases de treino são bons indicadores, mas no final nosso objetivo é classificar bem a base de teste.

# Classificação da base de teste: SVM Kernel Linear
table(te.svm_l, iris.te$Species)
            
te.svm_l     setosa versicolor virginica
  setosa         20          0         0
  versicolor      0         19         0
  virginica       0          1        20
# Classificação da base de teste: SVM Kernel Polinomial
table(te.svm.tune_p, iris.te$Species)
             
te.svm.tune_p setosa versicolor virginica
   setosa         20          0         0
   versicolor      0         20         5
   virginica       0          0        15
# Classificação da base de teste: SVM Kernel Radial
table(te.svm.tune_r, iris.te$Species)
             
te.svm.tune_r setosa versicolor virginica
   setosa         20          0         0
   versicolor      0         19         1
   virginica       0          1        19
# Classificação da base de teste: SVM Kernel Sigmoid
table(te.svm_s, iris.te$Species)
            
te.svm_s     setosa versicolor virginica
  setosa         20          0         0
  versicolor      0         19         1
  virginica       0          1        19

Independente do kernel usado previsões perfeitas são obtidas para as flores da espécie setosa.

As maiores dificuldades são obtidas na hora de classificar as flores da espécie virginica.

Os melhores resultados são obtidos com o kernel linear, contudo, cada vez que o algoritmo for processado diferentes parâmetros e resultados, consequentemente, podem ser obtidos. Logo, não podemos afirmar que o kernel linear é de longe o melhor.

Podemos dizer que para essa base de dados o kernel linear, radial, e sigmoid classificam de maneira muito similar. Quando olhamos para isso e para o grau de complexidade do classificador tendemos a escolher o kernel linear como melhor, já que ele é o mais simples de todos. Embora aqui os custos computacionais sejam muito próximos, dado que a base de dados não é muito grande.