Este documento muestra un ejemplo práctico del uso de la técnicas de Máquinas de Soporte Vectorial (SVM). Se presenta una introducción muy general de conceptos de SVM, posteriormete se desarrolla un caso práctico usando instrucciones en lenguaje R para su correcta comprensión.

1. Introducción

El método de clasificación-regresión Máquinas de Vector Soporte (Vector Support Machines, SVMs) fue desarrollado en la década de los 90, dentro de campo de la ciencia computacional.

Si bien originariamente se desarrolló como un método de clasificación binaria, su aplicación se ha extendido a problemas de clasificación múltiple y regresión. SVMs ha resultado ser uno de los mejores clasificadores para un amplio abanico de situaciones, por lo que se considera uno de los referentes dentro del ámbito de aprendizaje estadístico y machine learning. https://www.cienciadedatos.net/documentos/34_maquinas_de_vector_soporte_support_vector_machines

Las Máquinas Soporte Vectorial (SVM, del inglés Support Vector Machines) tienen su origen en los trabajos sobre la teoría del aprendizaje estadístico, inicialmente, las SVM fueron pensadas para aclarar y resolver problemas de clasificación binaria, su aplicación se ha extendido a problemas de clasificación múltiple y regresión. (Castañeda, 2019).

En un espacio p-dimensional, un hiperplano se define como un subespacio plano y afín de dimensiones p−1. El término afín significa que el subespacio no tiene por qué pasar por el origen. En un espacio de dos dimensiones, el hiperplano es un subespacio de 1 dimensión, es decir, una recta.

SVM también puede utilizarse como un método de regresión (support vector regression o SVR). SVR sigue los mismos principios que el SVM para clasificación, con alguna diferencia en cuanto al algoritmo (se establece un margen de tolerancia para las predicciones, épsilon).

La esencia de las SVM puede ser entendida sin el uso de fórmulas, para lo cual es necesario el conocimiento de cuatro conceptos básicos: el hiperplano de separación, el hiperplano óptimo, el margen suave y la función kernel o núcleo. (Cuevas, Alvares, Azcona, & Rodríguez, 2019)

  • Hiperplano de separación: Las SVM poseen una gran capacidad para aprender a partir de un conjunto de N muestras experimentales denominado conjunto de entrenamiento: \((x1,y1),(x2,y2),...,(xn,ym)\). Donde cada muestra \((xi,yi)\) para \(i=1…N\) está formado por un vector de n características \(xiϵRn\) y a una etiqueta yiϵR que indica la clase \(±1\) a la que pertenece cada muestra.

El objetivo es encontrar la función \(f:Rn→±1\) que separe los datos en dos clases y que clasifique o pronostique correctamente nuevas muestras perteneciente al conjunto de pruebas o de validación.

En un problema linealmente separable existen muchos hiperplanos que pueden clasificar los datos, pero las SVM no hayan uno cualquiera sino el único que maximiza la distancia entre el y el dato más cercano de cada clase. Imagen hiperplano de separación

  • El hiperplano de separación óptimo (HSO) y margen máximo: Está definido por el margen máximo de separación entre las dos clases.

Tomando como referencia la notación de la figura del hiperplano de separación, existen dos hiperplanos que definen las muestras a ambos lados de cada clase: \(w∗x+b=+1\) y \(w∗x+b=−1\) que son paralelos al HSO \(w∗x+b=0\) .

El margen máximo está dado por la distancia entre los hiperplanos paralelos y el HSO, cuyo resultado geométrico equivale a 2/||w||.

El vector de pesos w contiene la *ponderación de cada atributo, indicando qué tanto aportan en el proceso de clasificación o regresión.

Hallar el mejor hiperplano de separación es la esencia del problema de maximización con restricciones lineales.

La expresión final del clasificador buscado finalmente sería donde el signo resultante indicará la clase a la cual pertenece un dato determinado.

  • Margen suave: Cuando los datos de prueba no son linealmente separables se pueden adoptar dos técnicas para resolver el problema: con optimización “margen suave” y a través de kernel.

El proceso de optimización del hiperplano en este caso incorpora un parámetro de regularización o tuning parameter C, el cual controla la severidad permitida de las violaciones de las n observaciones sobre el margen e hiperplano, y a la vez, el equilibrio bias-varianza. Sin entrar en detalles matemáticos, si C>0, no más de C observaciones pueden encontrarse en el lado incorrecto del hiperplano. Si C es pequeño, los márgenes serán estrechos pues muy pocas observaciones podrán estar en el lado incorrecto del mismo (esto equivale a un modelo bastante bien ajustado a los datos, el cual puede tener poco bias pero mucha varianza). Conforme se incrementa C, mayor es la toleración a las violaciones sobre el margen, con lo que el margen será más ancho y habrá más vectores soporte (esto equivale a un modelo más flexible y con mayor bias pero menor varianza). Si C=0, el clasificador es equivalente al maximal margin classifier, pues no están permitidas violaciones sobre el margen (todas las observaciones deben estar correctamente clasificadas). En la práctica el parámetro C se escoge u optimiza por validación cruzada.

  • SVM no lineales con Kernel: La mayoría de los eventos reales no son separables linealmente por lo que se dificulta la definición del HSO. La figura 2 muestra un conjunto de datos donde no pueden ser separados linealmente por un hiperplano en Rn, pero si en un espacio de mayor dimensión Rh Imagen hiperplano lineal no lineal.Mapeo de datos a una mayor dimensión y separación lineal de las clases en el nuevo espacio

Cuando no existe una apropiada superficie lineal de decisión en el espacio original de los datos, se considera un mapeo del vector de entrada en un espacio de mayor dimensión \(Rh\) llamado espacio de características, que está dotado de producto escalar.

Eligiendo la transformación adecuada \(Rn→Rh\) se realiza el mapeo y se busca el HSO siguiendo lo dicho anteriormente del apartado anterior que será lineal en \(Rh\), pero representa un espacio no lineal en Rn

Este tipo de proyección hacia un espacio de característica es a través de las funciones denominadas kernels: \(K(xi,xk)=ᶲ(xi)∗ᶲ(xk)\).

Las funciones kernel permiten realizar las operaciones algebraicas en \(Rh\) de manera eficiente y sin conocer a la transformación ᶲ. Así, en principio cualquier técnica de análisis multivariado para datos \(xϵRn\) que se pueda reformular en un algoritmo computacional en términos de productos escalares, se puede generalizar a los datos transformados utilizando las funciones núcleos.

Existen varias funciones kernel o núcleos, destacando las siguientes cuatro, consideradas básicas:

  • Kernel lineal: \(K(xi,xj)=xiT∗xj\)

  • Kernel polinomial: \(K(xi,xj)=(p+ΥxiT∗xj)d,Υ>0\)

  • Kernel gaussiano RBF: \(K(xi,xj)=exp(−Υ||xi−xj||2),Υ>0\)

En R, las librerías e1071 y LiblineaR contienen los algoritmos necesarios para obtener modelos de clasificación simple, múltiple y regresión, basados en Support Vector Machines.

2. Caso SVM Bebidas

Para este ejemplo de clasificación se utiliza el conjunto de datos OJ, del paquete ISLR. Contiene información sobre compra de dos tipos de bebida (Citrus Hill y Minute Maid Orange Juice) por parte de 1070 clientes (las variables registran distintas características del cliente y el producto). Se generan modelos basados en SVM con tres tipos de kernel: lineal, polinómico y radial, que predigan qué tipo de bebida (Purchase) compra el consumidor, en función del conjunto de predictores.

2.1. Las librerías

Recordar que se quitan los message y warning con los parámetros y atributos {r message=FALSE, warning=FALSE}

# install.packages("ISLR")
library(ISLR)
library(knitr) # Para ver tablas mas amigables en formato html markdown
library(ggplot2) # Gráficas

library(dplyr) # Varias operaciones 

library(caret) # Para particionar datos. De entranamiento y de validación

#install.packages("e1071") # Para SVM
library(e1071)

2.2. Los datos

  • Se muestran la estructura de los datos con la función str().
  • Se muestran los estadísticos con summary(datos)
  • Se visualizan los primeros seis registros.
  • Se visualizan los últimos seis registros.
  • La variable independiente o variable de respuesta es la variable Purchase del conjunto de datos.
  • La variable Purchase es de tipo factor, lo cual es requisito para aplicar SVM.
  • CH = Citrus Hill y
  • MM = Minute Maid Orange Juice
datos <- OJ
str(datos)
## '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 ...
kable(summary(datos))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
CH:653 Min. :227.0 Min. :1.00 Min. :1.690 Min. :1.690 Min. :0.00000 Min. :0.0000 Min. :0.0000 Min. :0.0000 Min. :0.000011 Min. :1.190 Min. :1.390 Min. :-0.6700 No :714 Min. :0.0000 Min. :0.00000 Min. :0.000 Min. :0.000
MM:417 1st Qu.:240.0 1st Qu.:2.00 1st Qu.:1.790 1st Qu.:1.990 1st Qu.:0.00000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.:0.325257 1st Qu.:1.690 1st Qu.:1.750 1st Qu.: 0.0000 Yes:356 1st Qu.:0.0000 1st Qu.:0.00000 1st Qu.:0.140 1st Qu.:0.000
NA Median :257.0 Median :3.00 Median :1.860 Median :2.090 Median :0.00000 Median :0.0000 Median :0.0000 Median :0.0000 Median :0.600000 Median :2.090 Median :1.860 Median : 0.2300 NA Median :0.0000 Median :0.00000 Median :0.240 Median :2.000
NA Mean :254.4 Mean :3.96 Mean :1.867 Mean :2.085 Mean :0.05186 Mean :0.1234 Mean :0.1477 Mean :0.1617 Mean :0.565782 Mean :1.962 Mean :1.816 Mean : 0.1465 NA Mean :0.0593 Mean :0.02731 Mean :0.218 Mean :1.631
NA 3rd Qu.:268.0 3rd Qu.:7.00 3rd Qu.:1.990 3rd Qu.:2.180 3rd Qu.:0.00000 3rd Qu.:0.2300 3rd Qu.:0.0000 3rd Qu.:0.0000 3rd Qu.:0.850873 3rd Qu.:2.130 3rd Qu.:1.890 3rd Qu.: 0.3200 NA 3rd Qu.:0.1127 3rd Qu.:0.00000 3rd Qu.:0.300 3rd Qu.:3.000
NA Max. :278.0 Max. :7.00 Max. :2.090 Max. :2.290 Max. :0.50000 Max. :0.8000 Max. :1.0000 Max. :1.0000 Max. :0.999947 Max. :2.290 Max. :2.090 Max. : 0.6400 NA Max. :0.4020 Max. :0.25269 Max. :0.440 Max. :4.000

2.3. Distribución de la variable de respuesta Purchase

  • En función del tipo de refresco CH y MM
ggplot(data = OJ, aes(x = Purchase, y = ..count.., fill = Purchase)) +
geom_bar() +
labs(title = "Distribución de 'Purchase'") +
scale_fill_manual(values = c("darkgreen", "orangered2"), 
                  labels = c("Citrus Hill", "Orange Juice")) +
theme_bw() + theme(plot.title = element_text(hjust = 0.5))

## 2.4. Porcentajes % de la variable de respuesta * prop.table(): Determina la frecuencia relativa. * %>% : es un pipe que significa que el resutlado de la primeara expresión es la entrada de la segunda expresión. * round(): redondea

frecuencias <- prop.table(table(datos$Purchase)) %>% 
  round(digits = 2)
frecuencias
## 
##   CH   MM 
## 0.61 0.39
  • El 61 % de las preferencias de los clientes es para el refresco “CM” CH = Citrus Hill
  • El 39 % de las preferencias de los clientes es para el refresco “CM” MM = Minute Maid Orange Juice

2.5. Datos de entrenamiento y validación

Se dividen el conjunto de datos en un grupo de entrenamiento (para el ajuste de los modelos) y otro de test (para la evaluación o datos de validación de los mismos).

Esta división dependerá de la cantidad de observaciones con las que e tenga y la seguridad con la que se quiera obtener la estimación del test error.

En este ejemplo se opta por una división 80%-20%. * Se establece una semilla de inicio 123 * Se genera aleatoriamente una vriable entrena con el 80% de los registros para datos de entrenamiento * Los registros que no son de entranamiento serán para dtos de validación

set.seed(123)
entrena <- createDataPartition(y = datos$Purchase, p = 0.8, list = FALSE, times = 1)

# Datos entrenamiento
datos.entrenamiento <- datos[entrena, ]

# Datos validación
datos.validacion <- datos[-entrena, ]

2.5.1. Verificar los datos de entrenamiento y validación

  • Primero se muestran los head() y tail() (primeros y últimos registros) de los datos
  • Se tienen 1070 observaciones de los datos
kable(head(datos))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
CH 237 1 1.75 1.99 0.00 0.0 0 0 0.500000 1.99 1.75 0.24 No 0.000000 0.000000 0.24 1
CH 239 1 1.75 1.99 0.00 0.3 0 1 0.600000 1.69 1.75 -0.06 No 0.150754 0.000000 0.24 1
CH 245 1 1.86 2.09 0.17 0.0 0 0 0.680000 2.09 1.69 0.40 No 0.000000 0.091398 0.23 1
MM 227 1 1.69 1.69 0.00 0.0 0 0 0.400000 1.69 1.69 0.00 No 0.000000 0.000000 0.00 1
CH 228 7 1.69 1.69 0.00 0.0 0 0 0.956535 1.69 1.69 0.00 Yes 0.000000 0.000000 0.00 0
CH 230 7 1.69 1.99 0.00 0.0 0 1 0.965228 1.99 1.69 0.30 Yes 0.000000 0.000000 0.30 0
kable(tail(datos))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
1065 CH 251 7 1.86 2.09 0.1 0.00 0 0 0.484778 2.09 1.76 0.33 Yes 0.000000 0.053763 0.23 0
1066 CH 252 7 1.86 2.09 0.1 0.00 0 0 0.587822 2.09 1.76 0.33 Yes 0.000000 0.053763 0.23 0
1067 CH 256 7 1.86 2.18 0.0 0.00 0 0 0.670258 2.18 1.86 0.32 Yes 0.000000 0.000000 0.32 0
1068 MM 257 7 1.86 2.18 0.0 0.00 0 0 0.736206 2.18 1.86 0.32 Yes 0.000000 0.000000 0.32 0
1069 CH 261 7 1.86 2.13 0.0 0.24 0 0 0.588965 1.89 1.86 0.03 Yes 0.112676 0.000000 0.27 0
1070 CH 270 1 1.86 2.18 0.0 0.00 0 0 0.671172 2.18 1.86 0.32 No 0.000000 0.000000 0.32 1
  • Segundo los head() y tail() (primeros y últimos registros) de los datos de entrenamiento.
  • Se tienen 857 observaciones de los datos de enrenamiento.
kable(head(datos.entrenamiento))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
2 CH 239 1 1.75 1.99 0 0.3 0 1 0.600000 1.69 1.75 -0.06 No 0.150754 0 0.24 1
4 MM 227 1 1.69 1.69 0 0.0 0 0 0.400000 1.69 1.69 0.00 No 0.000000 0 0.00 1
5 CH 228 7 1.69 1.69 0 0.0 0 0 0.956535 1.69 1.69 0.00 Yes 0.000000 0 0.00 0
6 CH 230 7 1.69 1.99 0 0.0 0 1 0.965228 1.99 1.69 0.30 Yes 0.000000 0 0.30 0
7 CH 232 7 1.69 1.99 0 0.4 1 1 0.972182 1.59 1.69 -0.10 Yes 0.201005 0 0.30 0
8 CH 234 7 1.75 1.99 0 0.4 1 0 0.977746 1.59 1.75 -0.16 Yes 0.201005 0 0.24 0
kable(tail(datos.entrenamiento))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
1065 CH 251 7 1.86 2.09 0.1 0.00 0 0 0.484778 2.09 1.76 0.33 Yes 0.000000 0.053763 0.23 0
1066 CH 252 7 1.86 2.09 0.1 0.00 0 0 0.587822 2.09 1.76 0.33 Yes 0.000000 0.053763 0.23 0
1067 CH 256 7 1.86 2.18 0.0 0.00 0 0 0.670258 2.18 1.86 0.32 Yes 0.000000 0.000000 0.32 0
1068 MM 257 7 1.86 2.18 0.0 0.00 0 0 0.736206 2.18 1.86 0.32 Yes 0.000000 0.000000 0.32 0
1069 CH 261 7 1.86 2.13 0.0 0.24 0 0 0.588965 1.89 1.86 0.03 Yes 0.112676 0.000000 0.27 0
1070 CH 270 1 1.86 2.18 0.0 0.00 0 0 0.671172 2.18 1.86 0.32 No 0.000000 0.000000 0.32 1
  • Tercero los head() y tail() (primeros y últimos registros) de los datos de validación.
  • Se tienen 213 observaciones de los datos de validación.
kable(head(datos.validacion))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
1 CH 237 1 1.75 1.99 0.00 0.0 0 0 0.500000 1.99 1.75 0.24 No 0.000000 0.000000 0.24 1
3 CH 245 1 1.86 2.09 0.17 0.0 0 0 0.680000 2.09 1.69 0.40 No 0.000000 0.091398 0.23 1
10 CH 238 7 1.75 1.99 0.00 0.4 0 0 0.985757 1.59 1.75 -0.16 Yes 0.201005 0.000000 0.24 0
16 CH 278 7 2.06 2.13 0.00 0.0 0 0 0.795200 2.13 2.06 0.07 Yes 0.000000 0.000000 0.07 0
18 MM 268 2 1.86 2.18 0.00 0.0 0 1 0.400000 2.18 1.86 0.32 No 0.000000 0.000000 0.32 2
22 CH 258 1 1.76 2.18 0.00 0.0 0 0 0.680000 2.18 1.76 0.42 No 0.000000 0.000000 0.42 1
kable(tail(datos.validacion))
Purchase WeekofPurchase StoreID PriceCH PriceMM DiscCH DiscMM SpecialCH SpecialMM LoyalCH SalePriceMM SalePriceCH PriceDiff Store7 PctDiscMM PctDiscCH ListPriceDiff STORE
1040 CH 237 7 1.75 1.99 0 0.4 0 0 0.320000 1.59 1.75 -0.16 Yes 0.201005 0 0.24 0
1043 CH 239 1 1.75 1.99 0 0.3 0 1 0.651840 1.69 1.75 -0.06 No 0.150754 0 0.24 1
1053 CH 237 7 1.75 1.99 0 0.4 0 0 0.740928 1.59 1.75 -0.16 Yes 0.201005 0 0.24 0
1056 MM 227 1 1.69 1.69 0 0.0 0 0 0.320000 1.69 1.69 0.00 No 0.000000 0 0.00 1
1057 CH 228 7 1.69 1.69 0 0.0 0 0 0.256000 1.69 1.69 0.00 Yes 0.000000 0 0.00 0
1059 CH 233 7 1.75 1.99 0 0.4 1 0 0.523840 1.59 1.75 -0.16 Yes 0.201005 0 0.24 0

3. Modelo SVM Kernel lineal

Con el paquete e1071 se genera el modelo de SVM

A la hora de ajustar un support vector classifier, es importante tener en cuenta que el hiperparámetro C (cost) controla el equilibrio bias-varianza y la capacidad predictiva del modelo, ya que determina la severidad permitida respecto a las violaciones sobre el margen.

En otras palabras, se necesita fijar un margen de separación entre observaciones a priori. Por ello es recomendable evaluar distintos valores del mismo mediante validación cruzada y escoger el valor óptimo.

IMPORTANTE: Estandarizar los predictores cuando no estén medidos en la misma escala, para que los de mayor magnitud no tengan mayor influencia que el resto. Un argumento disponible en la función svm() para ello es scale = TRUE).

Para ajustar un support vector classifier, el kernel indicado en la función svm() ha de ser lineal. Se obtiene un valor de coste óptimo mediante validación cruzada utilizando la función tune() del paquete e1071.

3.1 Optimización de hiperparámetros mediante validación cruzada 10-fold

set.seed(325)
tuning <- tune(svm, Purchase ~ ., data = datos.entrenamiento, 
               kernel = "linear", 
               ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)), 
               scale = TRUE)

3.1.1 Resumen de la validación cruzada de tuning

El valor de coste que resulta en el menor error de validación (0,165) es 15.

summary(tuning)
## 
## Parameter tuning of 'svm':
## 
## - sampling method: 10-fold cross validation 
## 
## - best parameters:
##  cost
##    15
## 
## - best performance: 0.1656772 
## 
## - Detailed performance results:
##     cost     error dispersion
## 1  0.001 0.3009850 0.05276636
## 2  0.010 0.1691382 0.04602764
## 3  0.100 0.1679754 0.04037149
## 4  1.000 0.1703010 0.04099747
## 5  5.000 0.1703010 0.03755497
## 6 10.000 0.1668263 0.03560699
## 7 15.000 0.1656772 0.03338668
## 8 20.000 0.1668399 0.03479758
names(tuning)
## [1] "best.parameters"  "best.performance" "method"           "nparcomb"        
## [5] "train.ind"        "sampling"         "performances"     "best.model"

3.1.2. Graficando los costos de tuning

ggplot(data = tuning$performances, aes(x = cost, y = error)) +
  geom_line() +
  geom_point() +
  labs(title = "Error de validación ~ hiperparámetro C") +
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5))

  • El valor de coste que resulta en el menor error de validación (0,165) es 15.

3.2. Modelo óptimo obtenido

  • El tuning se utilizo para encontrar el mejor costo para el modelo de SVM
  • El tuning fué el proceso de optimización del hiperplano para encontar el mejor costo C
modelo <- tuning$best.model
summary(modelo)
## 
## Call:
## best.tune(method = svm, train.x = Purchase ~ ., data = datos.entrenamiento, 
##     ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 15, 20)), 
##     kernel = "linear", scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  15 
## 
## Number of Support Vectors:  345
## 
##  ( 173 172 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM

3.3. Modelo lineal (linear) SVM igual que óptimo obtenido

  • El modelo.lin da lo mismo que modelo
  • Se verifica con summary(modelo.lin)
modelo.lin <- svm(Purchase ~ ., data = datos.entrenamiento, kernel = "linear", cost = 15, scale = TRUE)

summary(modelo.lin)
## 
## Call:
## svm(formula = Purchase ~ ., data = datos.entrenamiento, kernel = "linear", 
##     cost = 15, scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  15 
## 
## Number of Support Vectors:  345
## 
##  ( 173 172 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM

3.4. Realizar predicciones

  • Se utilzia el conjunto de datos de entrenamiento
  • Se puede usar modelo o modelo.SVM ya que es el mismo
prediccion <- predict(modelo, datos.validacion)

3.4.1. Mostrar las predicciones

  • Las primeras y últimas diez de registro del conjunto de validación
kable(head(prediccion, 10))
x
1 CH
3 CH
10 CH
16 CH
18 CH
22 CH
26 CH
41 CH
45 CH
49 CH
kable(tail(prediccion, 10))
x
1011 CH
1014 CH
1020 CH
1039 MM
1040 MM
1043 CH
1053 CH
1056 MM
1057 MM
1059 CH
length(prediccion)
## [1] 213
nrow(datos.validacion)
## [1] 213

3.4.2. Generar matriz de confusión de la predicción

mat.confusion <- table(predicho  = prediccion, real = datos.validacion$Purchase)

mat.confusion
##         real
## predicho  CH  MM
##       CH 108  17
##       MM  22  66
  • De acuerdo a la métrica Accuracy que son la relación de los aciertos con respecto al total de observaciones.

  • La Exactitud ( en inglés, “Accuracy”) se refiere a lo cerca que está el resultado de una medición del valor verdadero.

  • En términos estadísticos, la exactitud está relacionada con el sesgo de una estimación. También se conoce como Verdadero Positivo (o “True positive rate”). Se representa por la proporción entre los positivos reales predichos por el algoritmo y todos los casos positivos. OJO: en inglés en ocasiones se usa el término “precision” para la exactitud y el término español precisión ser refiere a “accuracy”. Lo que puede llevar a confusión.

  • En forma práctica la Exactitud es la cantidad de predicciones positivas que fueron correctas

  • \(VP\) Verdaderos Positivos: es la cantidad de positivos que fueron acertados correctamente como positivos por el modelo.

  • \(VN\) Verdaderos Negativos: es la cantidad de negativos que fueron acertados correctamente como negativos por el modelo.

  • \(FN\) Falsos Negativos: es la cantidad de positivos que fueron clasificados incorrectamente como negativos. Error tipo 2 (Falsos Negativos)

  • \(FP\) Falsos Positivos: es la cantidad de negativos que fueron clasificados incorrectamente como positivos. Error tipo 1 (Falsos positivos)

Imagen matriz de confusion

  • \(VP+VN\) Son los casos.acertados

  • \(VP+FN+FP+VN\) son todos.los.casos

  • \(casos.acertados/todos.los.casos\)

  • \(exactitud=(VP+VN)/(VP+FN+FP+VN)\)

  • En R: \(round((mat.confusion[1,1]+mat.confusion[2,2])/nrow(datos.validacion)∗100,4)\)

  • Se utilizó el modelo de SVM con kernel tipo lineal con costo igual a 15

  • El modelo acierta en 174 de un total de 213

  • Representa el 81.6901 % en términos de exactitud estadística.

3.4.3. Gráfica de los valores reales Vs predichos

  • Se grafica el precio de venta y el precio de las bebidas CH.
ggplot(datos.validacion, aes(x = SalePriceCH, y = PriceCH)) + 
geom_point(aes(colour = factor(prediccion)))

3.4.4. Gráfica de los valores reales VS predichos

  • Se grafica el precio de venta y el precio de las bebidas MM.
ggplot(datos.validacion, aes(x = SalePriceMM, y = PriceMM)) + 
geom_point(aes(colour = factor(prediccion)))

4. Modelo SVM Kernel polinomial

4.1. Generar modelo SVM Polinomial (polynomial)

  • Se utiliza el mismo costo de 15
  • Se modifica el kernel a polynomial
  • Se puede generar polinomio de segundo, tercer grado secesivamente….
modelo.pol <- svm(Purchase ~ ., data = datos.entrenamiento, kernel = "polynomial", cost = 15, scale = TRUE)

summary(modelo.pol)
## 
## Call:
## svm(formula = Purchase ~ ., data = datos.entrenamiento, kernel = "polynomial", 
##     cost = 15, scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  polynomial 
##        cost:  15 
##      degree:  3 
##      coef.0:  0 
## 
## Number of Support Vectors:  342
## 
##  ( 177 165 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM

4.2. Realizar predicciones

  • Se utiliza el conjunto de datos de entrenamiento
  • Se usa el modelo.pol
prediccion <- predict(modelo.pol, datos.validacion)

4.2.1. Mostrar las predicciones

  • Las primeras y últimas diez de registro del conjunto de validación
kable(head(prediccion, 10))
x
1 CH
3 CH
10 CH
16 CH
18 CH
22 CH
26 CH
41 CH
45 CH
49 CH
kable(tail(prediccion, 10))
x
1011 CH
1014 CH
1020 CH
1039 MM
1040 MM
1043 CH
1053 CH
1056 MM
1057 CH
1059 MM
length(prediccion)
## [1] 213
nrow(datos.validacion)
## [1] 213

4.2.2. Generar matriz de confusión de la predicción

mat.confusion <- table(predicho  = prediccion, real = datos.validacion$Purchase)

mat.confusion
##         real
## predicho  CH  MM
##       CH 108  23
##       MM  22  60
  • Se utilizó el modelo de SVM con kernel tipo polinomial con costo igual a 15.
  • El modelo acierta en 168 de un total de 213
  • Representa el 78.8732 % en términos de exactitud estadística.

4.2.3. Gráfica de los valores reales Vs predichos

  • Se grafica el precio de venta y el precio de las bebidas CH.
ggplot(datos.validacion, aes(x = SalePriceCH, y = PriceCH)) + 
geom_point(aes(colour = factor(prediccion)))

4.2.4. Gráfica de los valores reales VS predichos

  • Se grafica el precio de venta y el precio de las bebidas MM.
ggplot(datos.validacion, aes(x = SalePriceMM, y = PriceMM)) + 
geom_point(aes(colour = factor(prediccion)))

5. Generar modelo SVM Kernel radial

5.1. Generar modelo SVM radial (radial)

  • Se utiliza el mismo costo de 15
  • Se modifica el kernel a radial
modelo.rad <- svm(Purchase ~ ., data = datos.entrenamiento, kernel = "radial", cost = 15, scale = TRUE)

summary(modelo.rad)
## 
## Call:
## svm(formula = Purchase ~ ., data = datos.entrenamiento, kernel = "radial", 
##     cost = 15, scale = TRUE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  radial 
##        cost:  15 
## 
## Number of Support Vectors:  340
## 
##  ( 173 167 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  CH MM

5.2. Realizar predicciones

  • Se utiliza el conjunto de datos de entrenamiento
  • Se usa el modelo.rad
prediccion <- predict(modelo.rad, datos.validacion)

5.2.1. Mostrar las predicciones

  • Las primeras y últimas diez de registro del conjunto de validación
kable(head(prediccion, 10))
x
1 MM
3 CH
10 CH
16 CH
18 CH
22 CH
26 CH
41 CH
45 CH
49 CH
kable(head(prediccion, 10))
x
1 MM
3 CH
10 CH
16 CH
18 CH
22 CH
26 CH
41 CH
45 CH
49 CH
kable(head(prediccion, 10))
x
1 MM
3 CH
10 CH
16 CH
18 CH
22 CH
26 CH
41 CH
45 CH
49 CH
kable(head(prediccion, 10))
x
1 MM
3 CH
10 CH
16 CH
18 CH
22 CH
26 CH
41 CH
45 CH
49 CH
### 5 .2.2. Generar matriz de confusión de la predicción
mat.confusion <- table(predicho  = prediccion, real = datos.validacion$Purchase)

mat.confusion
##         real
## predicho  CH  MM
##       CH 108  21
##       MM  22  62
  • Se utilizó el modelo de SVM con kernel tipo radial con costo igual a 15.
  • El modelo acierta en 170 de un total de 213
  • Representa el 79.8122 % en términos de exactitud estadística.

5.2.3. Gráfica de los valores reales Vs predichos

  • Se grafica el precio de venta y el precio de las bebidas CH.
ggplot(datos.validacion, aes(x = SalePriceCH, y = PriceCH)) + 
geom_point(aes(colour = factor(prediccion)))

5.2.4. Gráfica de los valores reales VS predichos

  • Se grafica el precio de venta y el precio de las bebidas MM.
ggplot(datos.validacion, aes(x = SalePriceMM, y = PriceMM)) + 
geom_point(aes(colour = factor(prediccion)))

6. Comentarios finales

  • En nuestro modelo de Kernel Radial se puede observar que el margen de error aumenta por los datos que son falsos negativos de este mismo modelo, En este caso se tiene la cantidad de 21 con una diferencia de 4 comparandolo con nuestro modelo de Kernel Lineal. Lo que finalmente nos brinda un porcentaje de acertividad del 79.81%

  • En nuestro modelo de Kernel Polinomial se llego al porcentaje de acertividad del 78.87% en este modelo aumentaron nuestros falsos negativos, en este modelo fueron 6 para una cantidad de 23.

  • Y en conclusion nuestro modelo con un mayor porcentaje de acertividad fue el de Kernel Lineal, este tuvo un porsentaje de acertividad del 81.69% en el cual acerto 174 de 213.

Bibliografía

  • Cuevas, V. M., Alvares, S., Azcona, M., & Rodríguez, A. I. (2019). Capacidad predictiva de las Máquinas de Soporte Vectorial. Una aplicación en la planificación financiera. Revista Cubana de Ciencias Informáticas, 59-75.
  • Castañeda, S. (01 de 07 de 2019). APLICACIÓN DE SUPPORT VECTOR MACHINE AL MERCADO COLOMBIANO. APLICACIÓN DE SUPPORT VECTOR MACHINE AL MERCADO COLOMBIANO, Trabajo de Grado. Colombia, Colombia, Colombia: Maestría en finanzas cuantitativas- Universidad del Rosario.