Implementações em R

Neste trabalho utilizaremos o software R pela praticidade e por ser software estatístico mais utilizado pela comunidade. No R diversos pacotes são destinado a Machine Learning e Statistical Learning, como pode ser visto em Cran Task Views.

Aqui, seguindo as recomendações do texto base da disciplina An Introduction to Statistical Learning, utilizaremos o pacote e1071 que é uma implementação em R baseada na LIBSVM.

## Pacote principal
library(e1071)

##-------------------------------------------
## Outros pacotes
## library(LiblineaR)
## library(klaR)
## library(kernlab)
## library(rdetools)

Conjunto de dados

Para a aplicação dos métodos de classificação via SVM serão utilizados os dados OJ (Oranje Juice) do pacote ISLR (pacote complementar do livro-texto da disciplina). Esses dados reference a 1070 observações sobre compra de sucos de laranja em um mercado. Os registros contemplam a informação de interesse, suco comprado CC para Citrus Hill e MM Minute Maid e demais 17 características sobre o cliente e produto.

##======================================================================
## Os dados
## help(OJ, h = "html")
data(OJ, package = "ISLR")
str(OJ)
## 'data.frame':    1070 obs. of  18 variables:
##  $ Purchase      : Factor w/ 2 levels "CH","MM": 1 1 1 2 1 1 1 1 1 1 ...
##  $ WeekofPurchase: num  237 239 245 227 228 230 232 234 235 238 ...
##  $ StoreID       : num  1 1 1 1 7 7 7 7 7 7 ...
##  $ PriceCH       : num  1.75 1.75 1.86 1.69 1.69 1.69 1.69 1.75 1.75 1.75 ...
##  $ PriceMM       : num  1.99 1.99 2.09 1.69 1.69 1.99 1.99 1.99 1.99 1.99 ...
##  $ DiscCH        : num  0 0 0.17 0 0 0 0 0 0 0 ...
##  $ DiscMM        : num  0 0.3 0 0 0 0 0.4 0.4 0.4 0.4 ...
##  $ SpecialCH     : num  0 0 0 0 0 0 1 1 0 0 ...
##  $ SpecialMM     : num  0 1 0 0 0 1 1 0 0 0 ...
##  $ LoyalCH       : num  0.5 0.6 0.68 0.4 0.957 ...
##  $ SalePriceMM   : num  1.99 1.69 2.09 1.69 1.69 1.99 1.59 1.59 1.59 1.59 ...
##  $ SalePriceCH   : num  1.75 1.75 1.69 1.69 1.69 1.69 1.69 1.75 1.75 1.75 ...
##  $ PriceDiff     : num  0.24 -0.06 0.4 0 0 0.3 -0.1 -0.16 -0.16 -0.16 ...
##  $ Store7        : Factor w/ 2 levels "No","Yes": 1 1 1 1 2 2 2 2 2 2 ...
##  $ PctDiscMM     : num  0 0.151 0 0 0 ...
##  $ PctDiscCH     : num  0 0 0.0914 0 0 ...
##  $ ListPriceDiff : num  0.24 0.24 0.23 0 0 0.3 0.3 0.24 0.24 0.24 ...
##  $ STORE         : num  1 1 1 1 0 0 0 0 0 0 ...

O exercício da obtenção de um classificador para esse conjunto de dados também foi proposto no exercício 8, pág. 371 de An Introduction to Statistical Learning. Seguindo as orientações do exercício particionaremos a base de dados em OJ.te e OJ.tr, as bases de teste e treino respectivamente. 800 observações serão tomadas para treino.

##----------------------------------------------------------------------
## Separando os dados em teste e treino
set.seed(2016)
index <- sample(nrow(OJ), 800)
OJ.tr <- OJ[index, ]
OJ.te <- OJ[-index, ]

A seguir serão propostos classificadores com base em SVM, considerando kernel linear (que adotando um valor de custo para classificações incorretas, tem o nome de Support Vector Classifiers), polynomial, radial e sigmoid.

Métodos de classificação

A função e1071::svm(...) é a função destinada à determinação dos vetores de suporte. O pacote e1071 provém também diversos métodos para obtenção de resultados do classificador definido pela svm.

Nas próximas seções todos os ajustes dos classificadores são realizados via função svm. Abaixo é exibido os argumentos da função.

## Para determinar o classificador
## help(svm, h = "html")
args(e1071:::svm.default)
## function (x, y = NULL, scale = TRUE, type = NULL, kernel = "radial", 
##     degree = 3, gamma = if (is.vector(x)) 1 else 1/ncol(x), coef0 = 0, 
##     cost = 1, nu = 0.5, class.weights = NULL, cachesize = 40, 
##     tolerance = 0.001, epsilon = 0.1, shrinking = TRUE, cross = 0, 
##     probability = FALSE, fitted = TRUE, ..., subset, na.action = na.omit) 
## NULL

Para comparação dos classificadores serão utilizados inspeções visuais da curva ROC, bem como os resultados obtidos pela classificação. Para exibição dos resultados a função compareROC foi implementada.

##======================================================================
## Funções utéis

library(Epi)
compareROC <- function(models) {
    ## Models uma lista nomeada com os resultados da função ROC do
    ## modelos classificadores a serem comparados 
    tableC <- sapply(models,
                     FUN = function(roc) {
                         index <- with(roc$res,
                                       which.max(sens + spec))
                         round(cbind(roc$res[index, ],
                                     "AUC" = roc$AUC), 4)
                     })
    rownames(tableC) <- c("sens", "spec", "pvp", "pvn", "prob", "AUC")
    return(tableC)
}

SVM kernel linear

\[ K(x_i, x_k) = \left \langle x_i, \, x_k \right \rangle \]

##-------------------------------------------
## Classificador default
(c0l <- svm(Purchase ~ ., kernel = "linear", data = OJ.tr,
           probability = TRUE))
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "linear", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  1 
##       gamma:  0.05555556 
## 
## Number of Support Vectors:  331
## Resumo do classificador
summary(c0l)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "linear", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  1 
##       gamma:  0.05555556 
## 
## Number of Support Vectors:  331
## 
##  ( 167 164 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
## Tabela de classificação no treino
pred.tr0l <- predict(c0l, newdata = OJ.tr, probability = TRUE)
table(pred.tr0l, OJ.tr$Purchase)
##          
## pred.tr0l  CH  MM
##        CH 442  81
##        MM  55 222
## Tabela de classificação no teste
pred.te0l <- predict(c0l, newdata = OJ.te, probability = TRUE)
table(pred.te0l, OJ.te$Purchase)
##          
## pred.te0l  CH  MM
##        CH 137  21
##        MM  19  93
## Probabilidades associadas as decisões
probs.tr0l <- attr(pred.tr0l, "probabilities")[, 2]
probs.te0l <- attr(pred.te0l, "probabilities")[, 2]
## Curvas ROC
par(mfrow = c(2, 2))
roc.te0l <- ROC(test = probs.tr0l, stat = OJ.tr$Purchase, plot = "ROC")
roc.tr0l <- ROC(test = probs.te0l, stat = OJ.te$Purchase, plot = "ROC")

Perceba que a função svm define alguns argumentos sem que o usuário precise especificá-los. Pelo default da função o método, denominado em sala como Maximal Margin Classifier. Abaixo definidos diferentes valores para o “custo” (que define quantos vetores de suportes serão utilizados na definição da fronteira).

Comparação de classificadores via validação cruzada Cuidado o tuning é realizado via validação cruzada sob simulação assim diferentes realizações da função geram diferentes resultados. O refinamento dos parâmetros considerados para validação cruzada pode ser feito em tune.control().

## Cuidado !
set.seed(2016)
(svm.tune <- tune(svm, Purchase ~ ., data = OJ.tr, kernel = "linear",
                  ranges = list(cost = c(0.001, 0.5, 1, 10))))
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost
##   0.5
## 
## - best performance: 0.17375
summary(svm.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost
##   0.5
## 
## - best performance: 0.17375 
## 
## - Detailed performance results:
##    cost   error dispersion
## 1 1e-03 0.34625 0.05104804
## 2 5e-01 0.17375 0.03458584
## 3 1e+00 0.17375 0.03458584
## 4 1e+01 0.18000 0.04005205
plot(svm.tune)

svm.tune$best.parameters
##   cost
## 2  0.5
##-------------------------------------------
## Definindo os melhor classificador nas validações cruzadas
c1l <- svm(Purchase ~ ., kernel = "linear", data = OJ.tr,
           cost = 0.5, probability = TRUE)

## Resumo do classificador
summary(c1l)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "linear", 
##     cost = 0.5, probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  0.5 
##       gamma:  0.05555556 
## 
## Number of Support Vectors:  332
## 
##  ( 166 166 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
## Gráficos condicionais das fronteiras de classificação
##     Cuidado! Os valores das demais covariáveis utilizadas para
##     classificação são definidas como 0. Isso pode ser alterado pelo
##     argumento slice()
plot(c1l, OJ.tr, WeekofPurchase ~ LoyalCH)

## Tabela de classificação no treino
pred.tr1l <- predict(c1l, newdata = OJ.tr, probability = TRUE)
table(pred.tr1l, OJ.tr$Purchase)
##          
## pred.tr1l  CH  MM
##        CH 443  80
##        MM  54 223
## Tabela de classificação no teste
pred.te1l <- predict(c1l, newdata = OJ.te, probability = TRUE)
table(pred.te1l, OJ.te$Purchase)
##          
## pred.te1l  CH  MM
##        CH 136  21
##        MM  20  93
## Probabilidades associadas as decisões
probs.tr1l <- attr(pred.tr1l, "probabilities")[, 2]
probs.te1l <- attr(pred.te1l, "probabilities")[, 2]
## Curvas ROC
par(mfrow = c(1, 2))
roc.te1l <- ROC(test = probs.tr1l, stat = OJ.tr$Purchase, plot = "ROC")
roc.tr1l <- ROC(test = probs.te1l, stat = OJ.te$Purchase, plot = "ROC")

##----------------------------------------------------------------------
## Comparando via AUC, Sensibilidade, Especificidade, Negativo/Positivo,
## Positivo/Negativo e Pontos de Corte respectivamente.
models.linear <- list("c0l.treino" = roc.tr0l, "c1l.treino" = roc.tr1l,
                      "c0l.teste" = roc.te0l, "c1l.teste" = roc.te1l)

## Armazenando o classificador de melhor desempenho
models.final <- list("linear" = roc.te0l)

kable(compareROC(models.linear), align = c("c", "c", "c", "c"))
c0l.treino c1l.treino c0l.teste c1l.teste
sens 0.8158 0.807 0.8515 0.8548
spec 0.8782 0.891 0.831 0.827
pvp 0.1329 0.1366 0.0983 0.0967
pvn 0.1696 0.156 0.2456 0.2493
prob 0.5 0.5375 0.3693 0.3634
AUC 0.8975 0.897 0.9064 0.9061

SVM kernel polinomial

\[ K(x_i, x_k) = (c_0 + \gamma \left \langle x_i, \, x_k \right \rangle)^d \]

##----------------------------------------------------------------------
##    kernel = polinomial default
(c0p <- svm(Purchase ~ ., kernel = "polynomial", data = OJ.tr,
            probability = TRUE))
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "polynomial", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  polynomial 
##        cost:  1 
##      degree:  3 
##       gamma:  0.05555556 
##      coef.0:  0 
## 
## Number of Support Vectors:  418
## Resumo do modelo
summary(c0p)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "polynomial", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  polynomial 
##        cost:  1 
##      degree:  3 
##       gamma:  0.05555556 
##      coef.0:  0 
## 
## Number of Support Vectors:  418
## 
##  ( 210 208 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
## Classificação dos dados de teste
pred.te0p <- predict(c0p, newdata = OJ.te, probability = TRUE)
probs.te0p <- attr(pred.te0p, "probabilities")[, 2]
roc.te0p <- ROC(test = probs.te0p, stat = OJ.te$Purchase, plot = "ROC")

## Tuning dos parâmetros (um pouco, talvez bastante, demorado)
set.seed(2016)
(svm.tune <- tune(svm, Purchase ~ ., data = OJ.tr,
                  kernel = "polynomial",
                  ranges = list(
                      cost = c(0.01, 1, 10),
                      gamma = c(0.01, 1/ncol(OJ), 0.1),
                      coef0 = c(-1, 0, 1),
                      degree = c(2, 3, 4, 5)
                      )))
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma coef0 degree
##     1  0.01     1      2
## 
## - best performance: 0.175
summary(svm.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma coef0 degree
##     1  0.01     1      2
## 
## - best performance: 0.175 
## 
## - Detailed performance results:
##      cost      gamma coef0 degree   error dispersion
## 1    0.01 0.01000000    -1      2 0.37875 0.04678927
## 2    1.00 0.01000000    -1      2 0.66125 0.04875178
## 3   10.00 0.01000000    -1      2 0.65750 0.05041494
## 4    0.01 0.05555556    -1      2 0.52625 0.04267529
## 5    1.00 0.05555556    -1      2 0.63250 0.04533824
## 6   10.00 0.05555556    -1      2 0.63000 0.04647281
## 7    0.01 0.10000000    -1      2 0.59750 0.02934469
## 8    1.00 0.10000000    -1      2 0.66000 0.03899786
## 9   10.00 0.10000000    -1      2 0.65625 0.03919768
## 10   0.01 0.01000000     0      2 0.37875 0.04678927
## 11   1.00 0.01000000     0      2 0.35500 0.04216370
## 12  10.00 0.01000000     0      2 0.22000 0.02513851
## 13   0.01 0.05555556     0      2 0.37875 0.04678927
## 14   1.00 0.05555556     0      2 0.19375 0.02224391
## 15  10.00 0.05555556     0      2 0.17625 0.02461509
## 16   0.01 0.10000000     0      2 0.35500 0.04216370
## 17   1.00 0.10000000     0      2 0.19125 0.02285978
## 18  10.00 0.10000000     0      2 0.18375 0.02285978
## 19   0.01 0.01000000     1      2 0.37875 0.04678927
## 20   1.00 0.01000000     1      2 0.17500 0.02700309
## 21  10.00 0.01000000     1      2 0.17750 0.02486072
## 22   0.01 0.05555556     1      2 0.30750 0.04297932
## 23   1.00 0.05555556     1      2 0.18250 0.02220485
## 24  10.00 0.05555556     1      2 0.18750 0.02886751
## 25   0.01 0.10000000     1      2 0.20875 0.02889757
## 26   1.00 0.10000000     1      2 0.17875 0.02360703
## 27  10.00 0.10000000     1      2 0.18375 0.03175973
## 28   0.01 0.01000000    -1      3 0.37875 0.04678927
## 29   1.00 0.01000000    -1      3 0.26000 0.03987829
## 30  10.00 0.01000000    -1      3 0.26875 0.07643307
## 31   0.01 0.05555556    -1      3 0.26000 0.04923018
## 32   1.00 0.05555556    -1      3 0.34625 0.04528076
## 33  10.00 0.05555556    -1      3 0.31875 0.04535738
## 34   0.01 0.10000000    -1      3 0.29500 0.05688683
## 35   1.00 0.10000000    -1      3 0.36125 0.03793727
## 36  10.00 0.10000000    -1      3 0.35875 0.04641674
## 37   0.01 0.01000000     0      3 0.37875 0.04678927
## 38   1.00 0.01000000     0      3 0.36625 0.04641674
## 39  10.00 0.01000000     0      3 0.31500 0.02486072
## 40   0.01 0.05555556     0      3 0.36500 0.04816061
## 41   1.00 0.05555556     0      3 0.18750 0.03385016
## 42  10.00 0.05555556     0      3 0.20375 0.02766993
## 43   0.01 0.10000000     0      3 0.31500 0.02486072
## 44   1.00 0.10000000     0      3 0.20500 0.03593976
## 45  10.00 0.10000000     0      3 0.20375 0.04291869
## 46   0.01 0.01000000     1      3 0.37875 0.04678927
## 47   1.00 0.01000000     1      3 0.18000 0.01881932
## 48  10.00 0.01000000     1      3 0.17875 0.03007514
## 49   0.01 0.05555556     1      3 0.20875 0.03007514
## 50   1.00 0.05555556     1      3 0.18500 0.02622022
## 51  10.00 0.05555556     1      3 0.19000 0.02874698
## 52   0.01 0.10000000     1      3 0.18625 0.02729087
## 53   1.00 0.10000000     1      3 0.18750 0.02568506
## 54  10.00 0.10000000     1      3 0.20250 0.03717451
## 55   0.01 0.01000000    -1      4 0.41375 0.03972562
## 56   1.00 0.01000000    -1      4 0.64375 0.05376453
## 57  10.00 0.01000000    -1      4 0.64500 0.05309844
## 58   0.01 0.05555556    -1      4 0.60875 0.04678927
## 59   1.00 0.05555556    -1      4 0.62000 0.04684490
## 60  10.00 0.05555556    -1      4 0.62000 0.04684490
## 61   0.01 0.10000000    -1      4 0.63750 0.03996526
## 62   1.00 0.10000000    -1      4 0.64750 0.04401704
## 63  10.00 0.10000000    -1      4 0.64750 0.04401704
## 64   0.01 0.01000000     0      4 0.37875 0.04678927
## 65   1.00 0.01000000     0      4 0.37875 0.04678927
## 66  10.00 0.01000000     0      4 0.36500 0.04816061
## 67   0.01 0.05555556     0      4 0.36500 0.04816061
## 68   1.00 0.05555556     0      4 0.24000 0.02486072
## 69  10.00 0.05555556     0      4 0.21000 0.03374743
## 70   0.01 0.10000000     0      4 0.31625 0.02766993
## 71   1.00 0.10000000     0      4 0.21250 0.03584302
## 72  10.00 0.10000000     0      4 0.19500 0.03593976
## 73   0.01 0.01000000     1      4 0.37875 0.04678927
## 74   1.00 0.01000000     1      4 0.18000 0.02371708
## 75  10.00 0.01000000     1      4 0.17875 0.02503470
## 76   0.01 0.05555556     1      4 0.19125 0.03120831
## 77   1.00 0.05555556     1      4 0.18750 0.02700309
## 78  10.00 0.05555556     1      4 0.19375 0.03963812
## 79   0.01 0.10000000     1      4 0.18375 0.01868043
## 80   1.00 0.10000000     1      4 0.18875 0.03251602
## 81  10.00 0.10000000     1      4 0.21625 0.04411554
## 82   0.01 0.01000000    -1      5 0.37875 0.04678927
## 83   1.00 0.01000000    -1      5 0.32375 0.05015601
## 84  10.00 0.01000000    -1      5 0.31375 0.04267529
## 85   0.01 0.05555556    -1      5 0.32250 0.04440971
## 86   1.00 0.05555556    -1      5 0.33875 0.04619178
## 87  10.00 0.05555556    -1      5 0.35500 0.04901814
## 88   0.01 0.10000000    -1      5 0.38375 0.04641674
## 89   1.00 0.10000000    -1      5 0.38250 0.02958040
## 90  10.00 0.10000000    -1      5 0.38375 0.03007514
## 91   0.01 0.01000000     0      5 0.37875 0.04678927
## 92   1.00 0.01000000     0      5 0.37875 0.04678927
## 93  10.00 0.01000000     0      5 0.36500 0.04816061
## 94   0.01 0.05555556     0      5 0.36375 0.04730589
## 95   1.00 0.05555556     0      5 0.24125 0.03120831
## 96  10.00 0.05555556     0      5 0.21125 0.03458584
## 97   0.01 0.10000000     0      5 0.30750 0.02220485
## 98   1.00 0.10000000     0      5 0.20125 0.03793727
## 99  10.00 0.10000000     0      5 0.21250 0.03486083
## 100  0.01 0.01000000     1      5 0.36500 0.04556741
## 101  1.00 0.01000000     1      5 0.17875 0.02433134
## 102 10.00 0.01000000     1      5 0.18500 0.02751262
## 103  0.01 0.05555556     1      5 0.18875 0.02531057
## 104  1.00 0.05555556     1      5 0.18375 0.03064696
## 105 10.00 0.05555556     1      5 0.19875 0.04505013
## 106  0.01 0.10000000     1      5 0.18625 0.02598744
## 107  1.00 0.10000000     1      5 0.19500 0.04456581
## 108 10.00 0.10000000     1      5 0.22000 0.02513851
svm.tune$best.parameters
##    cost gamma coef0 degree
## 20    1  0.01     1      2
##-------------------------------------------
## Definindo os melhor classificador com base nas validações cruzadas
c1p <- svm(Purchase ~ ., kernel = "polynomial", data = OJ.tr,
           cost = 10, gamma = 0.01, coef0 = 1, degree = 2,
           probability = TRUE)

## Resumo do modelo
summary(c1p)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "polynomial", 
##     cost = 10, gamma = 0.01, coef0 = 1, degree = 2, probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  polynomial 
##        cost:  10 
##      degree:  2 
##       gamma:  0.01 
##      coef.0:  1 
## 
## Number of Support Vectors:  331
## 
##  ( 165 166 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
plot(c1p, OJ.tr, WeekofPurchase ~ LoyalCH)

## Classificação dos dados de teste
pred.te1p <- predict(c1p, newdata = OJ.te, probability = TRUE)
probs.te1p <- attr(pred.te1p, "probabilities")[, 2]
roc.te1p <- ROC(test = probs.te1p, stat = OJ.te$Purchase, plot = "ROC")

##----------------------------------------------------------------------
## Comparando via AUC, Sensibilidade, Especificidade, Negativo/Positivo,
## Positivo/Negativo e Pontos de Corte respectivamente.
models.poly <- list("c0p.teste" = roc.te0p, "c1p.teste" = roc.te1p)

## Armazenando o classificador de melhor desempenho
models.final$polynomial <- roc.te1p

kable(compareROC(models.poly), align = c("c", "c"))
c0p.teste c1p.teste
sens 0.7982 0.8158
spec 0.891 0.8846
pvp 0.142 0.1321
pvn 0.1574 0.1622
prob 0.4689 0.5192
AUC 0.8891 0.9004

SVM kernel radial

\[ K(x_i, x_k) = \exp(-\gamma \left \| x_i, \, x_k \right \|^2 ) \]

##----------------------------------------------------------------------
##    kernel = radial basis
(c0r <- svm(Purchase ~ ., kernel = "radial", data = OJ.tr,
            probability = TRUE))
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "radial", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  radial 
##        cost:  1 
##       gamma:  0.05555556 
## 
## Number of Support Vectors:  373
## Resumo do modelo
summary(c0r)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "radial", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  radial 
##        cost:  1 
##       gamma:  0.05555556 
## 
## Number of Support Vectors:  373
## 
##  ( 187 186 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
## Classificação dos dados de teste
pred.te0r <- predict(c0r, newdata = OJ.te, probability = TRUE)
probs.te0r <- attr(pred.te0r, "probabilities")[, 2]
roc.te0r <- ROC(test = probs.te0r, stat = OJ.te$Purchase, plot = "ROC")

## Tuning dos parâmetros (um pouco demorado)
set.seed(2016)
(svm.tune <- tune(svm, Purchase ~ ., data = OJ.tr,
                  kernel = "radial",
                  ranges = list(
                      cost = c(0.01, 1, 10),
                      gamma = c(0.001, 0.01, 1/ncol(OJ), 0.1, 0.5, 1)
                  )))
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost      gamma
##     1 0.05555556
## 
## - best performance: 0.16625
summary(svm.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost      gamma
##     1 0.05555556
## 
## - best performance: 0.16625 
## 
## - Detailed performance results:
##     cost      gamma   error dispersion
## 1   0.01 0.00100000 0.37875 0.04678927
## 2   1.00 0.00100000 0.20375 0.03537988
## 3  10.00 0.00100000 0.18250 0.03238227
## 4   0.01 0.01000000 0.37875 0.04678927
## 5   1.00 0.01000000 0.18125 0.01792151
## 6  10.00 0.01000000 0.18125 0.02144923
## 7   0.01 0.05555556 0.37875 0.04678927
## 8   1.00 0.05555556 0.16625 0.02045490
## 9  10.00 0.05555556 0.18750 0.02568506
## 10  0.01 0.10000000 0.37875 0.04678927
## 11  1.00 0.10000000 0.17625 0.02461509
## 12 10.00 0.10000000 0.19000 0.02486072
## 13  0.01 0.50000000 0.37875 0.04678927
## 14  1.00 0.50000000 0.20125 0.03606033
## 15 10.00 0.50000000 0.20875 0.04752558
## 16  0.01 1.00000000 0.37875 0.04678927
## 17  1.00 1.00000000 0.20625 0.03019037
## 18 10.00 1.00000000 0.22125 0.04528076
svm.tune$best.parameters
##   cost      gamma
## 8    1 0.05555556
## Resumo do modelo
plot(c0r, OJ.tr, WeekofPurchase ~ LoyalCH)

## Armazenando o classificador de melhor desempenho
models.final$radial <- roc.te0r

SVM kernel sigmoid

\[ K(x_i, x_k) = \tanh(c_0 + \gamma \left \langle x_i, \, x_k \right \rangle ) \]

##----------------------------------------------------------------------
##    kernel = sigmoid default
(c0s <- svm(Purchase ~ ., kernel = "sigmoid", data = OJ.tr,
            probability = TRUE))
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "sigmoid", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  sigmoid 
##        cost:  1 
##       gamma:  0.05555556 
##      coef.0:  0 
## 
## Number of Support Vectors:  309
## Resumo do modelo
summary(c0s)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "sigmoid", 
##     probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  sigmoid 
##        cost:  1 
##       gamma:  0.05555556 
##      coef.0:  0 
## 
## Number of Support Vectors:  309
## 
##  ( 153 156 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
## Classificação dos dados de teste
pred.te0s <- predict(c0s, newdata = OJ.te, probability = TRUE)
probs.te0s <- attr(pred.te0s, "probabilities")[, 2]
roc.te0s <- ROC(test = probs.te0s, stat = OJ.te$Purchase, plot = "ROC")

## Tuning dos parâmetros (um pouco demorado)
set.seed(2016)
(svm.tune <- tune(svm, Purchase ~ ., data = OJ.tr,
                  kernel = "sigmoid",
                  ranges = list(
                      cost = c(0.01, 1, 10),
                      gamma = c(0.001, 0.01, 1/ncol(OJ), 0.1, 0.5, 1),
                      coef0 = c(-1, 0, 1)
                  )))
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma coef0
##    10  0.01     0
## 
## - best performance: 0.17125
summary(svm.tune)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost gamma coef0
##    10  0.01     0
## 
## - best performance: 0.17125 
## 
## - Detailed performance results:
##     cost      gamma coef0   error dispersion
## 1   0.01 0.00100000    -1 0.37875 0.04678927
## 2   1.00 0.00100000    -1 0.37875 0.04678927
## 3  10.00 0.00100000    -1 0.17875 0.03175973
## 4   0.01 0.01000000    -1 0.37875 0.04678927
## 5   1.00 0.01000000    -1 0.17875 0.03586723
## 6  10.00 0.01000000    -1 0.17750 0.02415229
## 7   0.01 0.05555556    -1 0.37875 0.04678927
## 8   1.00 0.05555556    -1 0.18500 0.03987829
## 9  10.00 0.05555556    -1 0.21125 0.03197764
## 10  0.01 0.10000000    -1 0.37875 0.04678927
## 11  1.00 0.10000000    -1 0.26500 0.06089609
## 12 10.00 0.10000000    -1 0.28750 0.04750731
## 13  0.01 0.50000000    -1 0.30500 0.06697844
## 14  1.00 0.50000000    -1 0.39250 0.07997395
## 15 10.00 0.50000000    -1 0.39625 0.08313518
## 16  0.01 1.00000000    -1 0.29625 0.06181570
## 17  1.00 1.00000000    -1 0.39875 0.06386020
## 18 10.00 1.00000000    -1 0.40375 0.06536489
## 19  0.01 0.00100000     0 0.37875 0.04678927
## 20  1.00 0.00100000     0 0.34625 0.05104804
## 21 10.00 0.00100000     0 0.18625 0.03030516
## 22  0.01 0.01000000     0 0.37875 0.04678927
## 23  1.00 0.01000000     0 0.18500 0.02934469
## 24 10.00 0.01000000     0 0.17125 0.02503470
## 25  0.01 0.05555556     0 0.37875 0.04678927
## 26  1.00 0.05555556     0 0.29875 0.04875178
## 27 10.00 0.05555556     0 0.27750 0.06313566
## 28  0.01 0.10000000     0 0.37875 0.04678927
## 29  1.00 0.10000000     0 0.31125 0.06220765
## 30 10.00 0.10000000     0 0.28625 0.04226652
## 31  0.01 0.50000000     0 0.31500 0.05645795
## 32  1.00 0.50000000     0 0.39000 0.05676462
## 33 10.00 0.50000000     0 0.39375 0.05870418
## 34  0.01 1.00000000     0 0.31125 0.05604128
## 35  1.00 1.00000000     0 0.40250 0.05645795
## 36 10.00 1.00000000     0 0.40500 0.06619626
## 37  0.01 0.00100000     1 0.37875 0.04678927
## 38  1.00 0.00100000     1 0.37875 0.04678927
## 39 10.00 0.00100000     1 0.18000 0.03395258
## 40  0.01 0.01000000     1 0.37875 0.04678927
## 41  1.00 0.01000000     1 0.18375 0.03488573
## 42 10.00 0.01000000     1 0.24250 0.04456581
## 43  0.01 0.05555556     1 0.37875 0.04678927
## 44  1.00 0.05555556     1 0.30875 0.04566256
## 45 10.00 0.05555556     1 0.32250 0.04322101
## 46  0.01 0.10000000     1 0.37875 0.04678927
## 47  1.00 0.10000000     1 0.37625 0.03747684
## 48 10.00 0.10000000     1 0.37125 0.03775377
## 49  0.01 0.50000000     1 0.33875 0.05756940
## 50  1.00 0.50000000     1 0.38875 0.06358776
## 51 10.00 0.50000000     1 0.36750 0.04174992
## 52  0.01 1.00000000     1 0.32625 0.05787019
## 53  1.00 1.00000000     1 0.39000 0.05737305
## 54 10.00 1.00000000     1 0.39500 0.05898446
svm.tune$best.parameters
##    cost gamma coef0
## 24   10  0.01     0
##-------------------------------------------
## Definindo os melhor classificador com base nas validações cruzadas
c1s <- svm(Purchase ~ ., kernel = "sigmoid", data = OJ.tr,
           cost = 10, gamma = 0.01, coef0 = 0, probability = TRUE)

## Resumo do modelo
summary(c1s)
## 
## Call:
## svm(formula = Purchase ~ ., data = OJ.tr, kernel = "sigmoid", 
##     cost = 10, gamma = 0.01, coef0 = 0, probability = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  sigmoid 
##        cost:  10 
##       gamma:  0.01 
##      coef.0:  0 
## 
## Number of Support Vectors:  343
## 
##  ( 173 170 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM
plot(c1s, OJ.tr, WeekofPurchase ~ LoyalCH)

## Classificação dos dados de teste
pred.te1s <- predict(c1s, newdata = OJ.te, probability = TRUE)
probs.te1s <- attr(pred.te1s, "probabilities")[, 2]
roc.te1s <- ROC(test = probs.te1s, stat = OJ.te$Purchase, plot = "ROC")

##----------------------------------------------------------------------
## Comparando via AUC, Sensibilidade, Especificidade, Negativo/Positivo,
## Positivo/Negativo e Pontos de Corte respectivamente.
models.sigmoid <- list("c0s.teste" = roc.te0s, "c1s.teste" = roc.te1s)

## Armazenando o classificador de melhor desempenho
models.final$sigmoid <- roc.te1s

kable(compareROC(models.sigmoid), align = c("c", "c"))
c0s.teste c1s.teste
sens 0.5789 0.8246
spec 0.8333 0.8718
pvp 0.2697 0.1282
pvn 0.2826 0.1754
prob 0.4862 0.4871
AUC 0.7142 0.8946

Comparação dos ajustes

## Comparação visual
plot(0, 0, xlim = c(0, 1), ylim = c(0, 1), type = "n",
     xlab = "1-Specificity", ylab = "Sensitivity")
abline(v = seq(0, 1, 0.1), h = seq(0, 1, 0.1), col = "gray90")
abline(0, 1, col = "gray40")
##
sapply(1:length(models.final), function(i) {
    with(models.final[[i]],
         points(1 - res[, 2], res[, 1], type = "l", col = i))
})
## [[1]]
## NULL
## 
## [[2]]
## NULL
## 
## [[3]]
## NULL
## 
## [[4]]
## NULL
##
legend(x = 0.7, y = 0.4, lwd = 1,
       bty = "n", col = 1:length(models.final),
       legend = names(models.final))

## Comparação das medidas de classificação
kable(compareROC(models.final), align = c("c", "c", "c", "c"))
linear polynomial radial sigmoid
sens 0.8515 0.8158 0.8333 0.8246
spec 0.831 0.8846 0.8782 0.8718
pvp 0.0983 0.1321 0.1218 0.1282
pvn 0.2456 0.1622 0.1667 0.1754
prob 0.3693 0.5192 0.4915 0.4871
AUC 0.9064 0.9004 0.8954 0.8946

Sabatina

Proponha um classificador baseado em Supporte Vector Machine para classificar a espécie das plantas no conjunto de dados iris do R. Considere ao menos 2 classificadores para comparação via classificação em uma base de teste.

Para particionar os dados em base de treino e teste, pode-se seguir os comandos abaixo.

##======================================================================
## Sabatina
data(iris, package = "datasets")

## Dados balanceados com base na espécie
table(iris$Species)
## 
##     setosa versicolor  virginica 
##         50         50         50
## Utilize como semente seu GRR
set.seed(20124689)
index <- matrix(c(0, 50, 100), ncol = 3, nrow = 30, byrow = TRUE) +
    replicate(3, sample(1:50, 30))

## Particione os dados em dados de treino e dados de teste
iris.tr <- iris[c(index), ]
iris.te <- iris[-c(index), ]

## Dados balanceados para treino também
table(iris.tr$Species)
## 
##     setosa versicolor  virginica 
##         30         30         30
table(iris.te$Species)
## 
##     setosa versicolor  virginica 
##         20         20         20