- Emerson Rigoni
- Henrique Aparecido Laureano [Lattes, GitLab, GitHub, LEG GitLab]
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
library(e1071)
\[ 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).
\[ 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.
\[ 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.
\[ 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.
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.