SUPORT VECTOR MACHINES

Missão a ser entregue em 17/08 para a disciplina de Aprendizagem de Máquina.
Alunos:
- José Marcus C. M. Júnior
- Marcos de Souza Oliveira

Arquivo a ser importado

Arquivo provemiente do site “https://archive.ics.uci.edu/ml/machine-learning-databases/glass/”, com o nome glass.data O estudo da classificação dos tipos de vidro foi motivado por investigação criminológica. No local do crime, o vidro deixado pode ser usado como prova … se estiver corretamente identificado!

glass <- read.csv(file.choose(), header = FALSE, sep = ",")
head(glass) #para ver as primeiras linhas do arquivo

Adicionando os nomes das colunas

  1. Número de identificação: 1 a 214
  2. RI: índice de refração
  3. Na: Sódio (medida da unidade: porcentagem em peso no óxido correspondente, assim como os atributos 4-10)
  4. Mg: Magnésio
  5. Al: Alumínio
  6. Si: Silício
  7. K: Potássio
  8. Ca: Cálcio
  9. Ba: Bário
  10. Fe: Ferro
  11. Tipo de vidro: (atributo de classe)
  • 1 building_windows_float_processed
  • 2 building_windows_non_float_processed
  • 3 vehicle_windows_float_processed
  • 4 vehicle_windows_non_float_processed (nenhum em esta base de dados)
  • 5 recipientes
  • 6 talheres
  • 7 faróis

A coluna tipo deve ser configurada como fator

colnames(glass) <- c("id","ri","na","mg","al","si","k","ca","ba","fe","tipo")
head(glass)
class(glass$tipo)
## [1] "integer"
glass$tipo <- as.factor(glass$tipo)
class(glass$tipo)
## [1] "factor"

Análise exploratória dos dados

summary(glass)
##        id               ri              na              mg       
##  Min.   :  1.00   Min.   :1.511   Min.   :10.73   Min.   :0.000  
##  1st Qu.: 54.25   1st Qu.:1.517   1st Qu.:12.91   1st Qu.:2.115  
##  Median :107.50   Median :1.518   Median :13.30   Median :3.480  
##  Mean   :107.50   Mean   :1.518   Mean   :13.41   Mean   :2.685  
##  3rd Qu.:160.75   3rd Qu.:1.519   3rd Qu.:13.82   3rd Qu.:3.600  
##  Max.   :214.00   Max.   :1.534   Max.   :17.38   Max.   :4.490  
##        al              si              k                ca        
##  Min.   :0.290   Min.   :69.81   Min.   :0.0000   Min.   : 5.430  
##  1st Qu.:1.190   1st Qu.:72.28   1st Qu.:0.1225   1st Qu.: 8.240  
##  Median :1.360   Median :72.79   Median :0.5550   Median : 8.600  
##  Mean   :1.445   Mean   :72.65   Mean   :0.4971   Mean   : 8.957  
##  3rd Qu.:1.630   3rd Qu.:73.09   3rd Qu.:0.6100   3rd Qu.: 9.172  
##  Max.   :3.500   Max.   :75.41   Max.   :6.2100   Max.   :16.190  
##        ba              fe          tipo  
##  Min.   :0.000   Min.   :0.00000   1:70  
##  1st Qu.:0.000   1st Qu.:0.00000   2:76  
##  Median :0.000   Median :0.00000   3:17  
##  Mean   :0.175   Mean   :0.05701   5:13  
##  3rd Qu.:0.000   3rd Qu.:0.10000   6: 9  
##  Max.   :3.150   Max.   :0.51000   7:29

Analisando a correlação entre as variáveis do modelo

cor(glass[,2:10])
##               ri          na           mg          al          si            k
## ri  1.0000000000 -0.19188538 -0.122274039 -0.40732603 -0.54205220 -0.289832711
## na -0.1918853790  1.00000000 -0.273731961  0.15679367 -0.06980881 -0.266086504
## mg -0.1222740393 -0.27373196  1.000000000 -0.48179851 -0.16592672  0.005395667
## al -0.4073260341  0.15679367 -0.481798509  1.00000000 -0.00552372  0.325958446
## si -0.5420521997 -0.06980881 -0.165926723 -0.00552372  1.00000000 -0.193330854
## k  -0.2898327111 -0.26608650  0.005395667  0.32595845 -0.19333085  1.000000000
## ca  0.8104026963 -0.27544249 -0.443750026 -0.25959201 -0.20873215 -0.317836155
## ba -0.0003860189  0.32660288 -0.492262118  0.47940390 -0.10215131 -0.042618059
## fe  0.1430096093 -0.24134641  0.083059529 -0.07440215 -0.09420073 -0.007719049
##            ca            ba           fe
## ri  0.8104027 -0.0003860189  0.143009609
## na -0.2754425  0.3266028795 -0.241346411
## mg -0.4437500 -0.4922621178  0.083059529
## al -0.2595920  0.4794039017 -0.074402151
## si -0.2087322 -0.1021513105 -0.094200731
## k  -0.3178362 -0.0426180594 -0.007719049
## ca  1.0000000 -0.1128409671  0.124968219
## ba -0.1128410  1.0000000000 -0.058691755
## fe  0.1249682 -0.0586917554  1.000000000

Gráfico de correlação (Rosa = baixa correlação, vermelho = alta correlação)

library(lattice)
cor <- cor(glass[,2:10]) 
rgb.palette <- colorRampPalette(c("pink", "red"), space = "rgb")
levelplot(cor, main="Correlation Glass Dataset", xlab="", ylab="", col.regions=rgb.palette(120))

Gráfico de dispersão dos dados

pairs(glass[2:10], main = "Glass Data", pch = 21, bg = c("red", "green3", "blue","yellow","purple","deeppink")[unclass(glass$tipo)])

Vamos separar os dados em treino e teste

Para esta divisão criamos um vetor ‘amostra’ com ‘1’ e ‘2’, em que a probabilidade de aparecer ‘1’ é de 70% e ‘2’ é de 30%. Em seguida criamos o arquivo de treino e o arquivo de teste.

set.seed(88)
amostra <- sample(2,214,replace = T,prob = c(0.7,0.3))
glass_treino <- glass[amostra==1,]
glass_teste <- glass[amostra==2,]
dim(glass_teste)
## [1] 64 11
dim(glass_treino)
## [1] 150  11

Modelos de Kernel aplicados

Se nada for informado na função svm, o padrão é o radial, que é o caso do modelo1, aplicamos diferentes tipos de kernel nos demais modelos:
- Radial para o modelo 1
- Polynomial para o modelo 2
- Sigmoid para o modelo 3
- Linear para o modelo 4

Kernel Radial

library(e1071)
modelo1 <- svm(tipo ~ . , data = glass_treino)
summary(modelo1)
## 
## Call:
## svm(formula = tipo ~ ., data = glass_treino)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  radial 
##        cost:  1 
## 
## Number of Support Vectors:  109
## 
##  ( 23 43 13 9 9 12 )
## 
## 
## Number of Classes:  6 
## 
## Levels: 
##  1 2 3 5 6 7
predicao1 <- predict(modelo1, glass_teste)
t1 <- table(predicao1,glass_teste$tipo)
t1
##          
## predicao1  1  2  3  5  6  7
##         1 23  1  0  0  0  0
##         2  0 24  3  0  0  2
##         3  0  0  1  0  0  0
##         5  0  1  0  3  0  0
##         6  0  1  0  0  0  0
##         7  0  0  0  0  0  5

Kernel Polynomial

Kernels polinomiais são popularmente usados, especialmente com grau 2. Na verdade, o inventor das máquinas de vetores de suporte, Vladimir N Vapnik, desenvolveu usando um kernel de grau 2 para classificar dígitos manuscritos. Os núcleos polinomiais são dados pela seguinte equação:
\[\begin{equation} k(x,x') = (1+x*x')^k \end{equation}\]

modelo2 <- svm(tipo ~ . ,kernel = "polynomial", data = glass_treino)
summary(modelo2)
## 
## Call:
## svm(formula = tipo ~ ., data = glass_treino, kernel = "polynomial")
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  polynomial 
##        cost:  1 
##      degree:  3 
##      coef.0:  0 
## 
## Number of Support Vectors:  126
## 
##  ( 41 47 13 9 8 8 )
## 
## 
## Number of Classes:  6 
## 
## Levels: 
##  1 2 3 5 6 7
predicao2 <- predict(modelo2,glass_teste)
t2 <- table(predicao2,glass_teste$tipo)
t2
##          
## predicao2  1  2  3  5  6  7
##         1 20  1  0  0  0  0
##         2  3 24  4  0  0  1
##         3  0  0  0  0  0  0
##         5  0  1  0  3  0  1
##         6  0  1  0  0  0  0
##         7  0  0  0  0  0  5

Kernel Sigmoid

modelo3 <- svm(tipo ~ . ,kernel = "sigmoid", data = glass_treino)
summary(modelo3)
## 
## Call:
## svm(formula = tipo ~ ., data = glass_treino, kernel = "sigmoid")
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  sigmoid 
##        cost:  1 
##      coef.0:  0 
## 
## Number of Support Vectors:  113
## 
##  ( 28 40 13 10 9 13 )
## 
## 
## Number of Classes:  6 
## 
## Levels: 
##  1 2 3 5 6 7
predicao3 <- predict(modelo3,glass_teste)
t3 <- table(predicao3, glass_teste$tipo)
t3
##          
## predicao3  1  2  3  5  6  7
##         1 22  1  0  0  0  0
##         2  1 24  4  3  0  1
##         3  0  0  0  0  0  0
##         5  0  2  0  0  0  1
##         6  0  0  0  0  0  0
##         7  0  0  0  0  0  5

Kernel Linear

modelo4 <- svm(tipo ~ . ,kernel = "linear", data = glass_treino)
summary(modelo4)
## 
## Call:
## svm(formula = tipo ~ ., data = glass_treino, kernel = "linear")
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  1 
## 
## Number of Support Vectors:  70
## 
##  ( 14 26 12 7 5 6 )
## 
## 
## Number of Classes:  6 
## 
## Levels: 
##  1 2 3 5 6 7
predicao4 <- predict(modelo4, glass_teste)
t4 <- table(predicao4,glass_teste$tipo)
t4
##          
## predicao4  1  2  3  5  6  7
##         1 23  0  0  0  0  0
##         2  0 26  2  0  0  0
##         3  0  0  2  0  0  1
##         5  0  1  0  3  0  1
##         6  0  0  0  0  0  0
##         7  0  0  0  0  0  5

Calculando as taxas de erro

## [1] "Taxa de erro em percentual"
## [1] 12.5
## [1] 18.75
## [1] 20.3125
## [1] 7.8125

Medição de acurácia

accrcy <- function(matrx){
return( sum(diag(matrx)/sum(matrx)))}
accrcy(t1)
## [1] 0.875
accrcy(t2)
## [1] 0.8125
accrcy(t3)
## [1] 0.796875
accrcy(t4)
## [1] 0.921875

Medição de precisão

precsn <- function(matrx){
return(diag(matrx) / rowSums(matrx)) }
precsn(t1)
##         1         2         3         5         6         7 
## 0.9583333 0.8275862 1.0000000 0.7500000 0.0000000 1.0000000
precsn(t2)
##        1        2        3        5        6        7 
## 0.952381 0.750000      NaN 0.600000 0.000000 1.000000
precsn(t3)
##         1         2         3         5         6         7 
## 0.9565217 0.7272727       NaN 0.0000000       NaN 1.0000000
precsn(t4)
##         1         2         3         5         6         7 
## 1.0000000 0.9285714 0.6666667 0.6000000       NaN 1.0000000

Comentarios

As seguintes taxas de erro foram obtidas com os diferentes tipos de kernel:
- Radial……………… 12.5%
- Polinomial………….. 18.75%
- Sigmoid…………….. 20.31%
- Linear……………… 7.81%
No geral, o kernel Linear foi o que melhor conseguiu ajustar a classificação dos dados, com a menor taxa de erro e melhor acurácia entre os diferentes tipos de kernel’s.
Isto significa que o banco de dados GLASS é mais eficientemente classificável com um kernel linear , em termos gerais.
Quando analisamos um a um os tipos de vidro, a classificação do kernel linear tem um desempenho mediano para os tipos 3 e 5, acertando somente 66% e 60% respectivamente. Para os tipos 3 e 5, o Kernel Radial tem o melhor desempenho de todos mas é o segundo colocado no desempenho geral, bem como não acerta nada para o tipo 6. O Kernel Linear é o único que consegue classificar todos os tipos, já os outros tipos de kernel’s tem péssimo desempenho, (100% de erro) em pelo menos um tipo de vidro.