6/2/2020

Introducción

Resumen de las librerias y funciones útiles para resolver problemas de Support Vector Machine (SVM) y Support Vector Regression (SVR) en R.

# install.packages("e1071","caret","hydroGOF")

library(e1071) # svm; tune.svm
library(ggplot2) # gráficos
library(caret)  # createDataPartition; 
                # confusionMatrix; 
                # R2 (R squared)
library(hydroGOF) # mse   (Mean Squared Error)
                  # mae   (Mean Absolute Error)
                  # rmse  (Root Mean Square Error)
library(knitr)
library(kableExtra)

Función “svm

Función incorporada en el paquete “e1071” que sirve para SVM y SVR. Los argumentos de la función son:

  • formula’: modelo
  • data’: data frame que contiene las variables del modelo
  • type’: “C-classification”,“eps-regression”
  • kernel’: “linear”,“polynomial”,“radial basis”,“sigmoid”
  • degree’: grado para el kernel polinomial
  • gamma’: parámetro para kernels excepto lineal
  • coef0’: parámetro para kernels de tipo “polinomial” y “sigmoid”
  • cost’: coste por infringir las restricciones

Función “tune.svm

Función incorporada en el paquete “e1071” que sirve para buscar el valor óptimo de los hiperparámetros.

Por ejemplo:

tuning <- tune.svm(x, y, type, kernel, degree, 
                   cost = 10^(-1:2), 
                   gamma = c(0.1, 1, 10), 
                   coef0 = c(0.1, 1, 10))

summary(tuning)
names(tuning)
## "best.parameters" "best.performance"
## "method" "nparcomb"        
## "train.ind" "sampling"
## "performances" "best.model"

Función “createDataPartition” y “confusionMatrix

createDataPartition: Función incorporada en el paquete “caret” que sirve para dividir los datos en entrenamiento y testeo. Los argumentos de la función son:

  • y’: vector con los valores de la variable “y”
  • p’: porcentaje de datos que se usarán para el entrenamiento
  • list’: “FALSE”, para que se guarde como matriz y no lista

confusionMatrix: Función que sirve para calcular una tabla cruzada de los datos observados y predichos. Además, incorpora los estadísticos asociados a dichos cálculos.

confusionMatrix(predichos,observados)

Pasos genéricos a seguir

  1. Descriptivos y estudio de correlación entre las variables
  2. Representar las variables (en caso de que las dimensiones lo permitan)
  3. Dividir el conjunto de datos en “train” (80%) y “test” (20%)
  4. Generar el modelo con la funcion svm, especificando el dataframe que contiene los datos, kernel y coste a asumir
  5. Obtener los coeficientes lineales, los vectores soporte, etc.
  6. Graficar con plot() directamente el modelo junto a los datos o generando una malla de puntos, sobreponiendo los puntos y los hiperplanos
  7. Comprobar la precisión del modelo sobre los datos de entrenamiento y sobre los datos de testeo

División de los datos en “train” y “test” (1)

# Adjudico aleatoriamente un 80% de los datos como entrenamiento
df[,"train"] <- ifelse(runif(nrow(df))<0.8,1,0)
# Separamos los dos sets: train y test
trainset <- df[df$train==1,]
testset <- df[df$train==0,]
# Vemos en qué columna se encuentran los datos 0 y 1 que deciden si
# se trata de un registro de entrenamiento o de testeo
trainColNum <- grep("train",names(trainset))
# Elimino dicha columna
trainset <- trainset[,-trainColNum]
testset <- testset[,-trainColNum]

División de los datos en “train” y “test” (2)

inTrain <- createDataPartition(y=spam$type, p=0.8, list=FALSE)
training <- spam[inTrain,]
testing <- spam[-inTrain,]

¿Cómo identificar el kernel?

Objetivo: solución lineal en el espacio de características (transformado). En otras palabras, llevar los datos a un espacio vectorial donde se pueda aplicar métodos lineales e identificar patrones.

LINEAL: aproximar nuestra función con una función lineal.

POLINOMIAL: resolver nuestro problema con un kernel polinomial con diferentes grados d y coeficientes R.

RADIAL: resolver nuestro problema con un kernel gaussiano con diferentes valores de γ.

SIGMOID: resolver nuestro problema con un kernel sigmoidal con diferentes valores de γ y R.

Precisión a partir del error y R2 (1)

## EJEMPLO PARA LINEAL ##

# test$medv --> OBS. Valores variable respuesta de testeo
# pred_lin --> PRED. Valores predichos sobre los valores 
# de testeo a partir del modelo 

mse_lin = mse(test$medv, pred_lin) 
mae_lin = mae(test$medv, pred_lin)
rmse_lin = rmse(test$medv, pred_lin)
r2_lin = R2(test$medv, pred_lin, form = "traditional")

Precisión a partir del error y R2 (2)

prec_lin <- c(17.89,3.21,4.23,65.89)
prec_pol <- c(12.42,2.72,3.52,82.63)
prec_rad <- c(6.03,1.88,2.46,91.41)
precisiones <- data.frame(prec_lin,prec_pol,prec_rad)
colnames(precisiones) <- c("Lineal","Polinómico","Radial")
rownames(precisiones) <- c("MSE","MAE","RMSE","R2")
kable(precisiones, digits=2)%>%
  kable_styling(bootstrap_options = "striped")
Lineal Polinómico Radial
MSE 17.89 12.42 6.03
MAE 3.21 2.72 1.88
RMSE 4.23 3.52 2.46
R2 65.89 82.63 91.41

Otras formas de calcular la precisión sobre train y test

# Predecimos con los datos de entrenamiento
pred_train <- predict(svm_model,trainset)
mean(pred_train==trainset$y) # PRECISIÓN
# Predecimos con los datos de testeo
pred_test <- predict(svm_model,testset)
mean(pred_test==testset$y) # PRECISIÓN

Bibliografía interesante