SVM - Máquinas de soporte vectorial

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.

Las Máquinas de Vector Soporte se fundamentan en el Maximal Margin Classifier, que a su vez, se basa en el concepto de hiperplano. A lo largo de este ensayo se introducen por orden cada uno de estos conceptos. Comprender los fundamentos de las SVMs requiere de conocimientos sólidos en álgebra lineal. En este ensayo no se profundiza en el aspecto matemático, pero puede encontrarse una descripción detallada en el libro Support Vector Machines Succinctly by Alexandre Kowalczyk.

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

Hiperplano y Maximal Margin Classifier

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. En un espacio tridimensional, un hiperplano es un subespacio de dos dimensiones, un plano convencional. Para dimensiones p>3 no es intuitivo visualizar un hiperplano, pero el concepto de subespacio con p−1 dimensiones se mantiene.

La definición matemática de un hiperplano es bastante simple. En el caso de dos dimensiones, el hiperplano se describe acorde a la ecuación de una recta:

\[ \beta_0 + \beta_1x_1 + \beta_2x_2 = 0 \]

Dados los parámetros β0, β1 y β2 , todos los pares de valores x=(x1,x2) para los que se cumple la igualdad son puntos del hiperplano. Esta ecuación puede generalizarse para p-dimensiones:

\[ \beta_0 + \beta_1x_1 + \beta_2x_2 + ... + \beta_px_p = 0 \]

y de igual manera, todos los puntos definidos por el vector (x=x1,x2,…,xp) que cumplen la ecuación pertenecen al hiperplano.

Cuando x no satisface la ecuación:

\[ \beta_0 + \beta_1x_1 + \beta_2x_2 + ... + \beta_px_p < 0 \]

el punto x cae a un lado o al otro del hiperplano. Así pues, se puede entender que un hiperplano divide un espacio p-dimensional en dos mitades. Para saber en qué lado del hiperplano se encuentra un determinado punto x , solo hay que calcular el signo de la ecuación.

La siguiente imagen muestra el hiperplano de un espacio bidimensional. La ecuación que describe el hiperplano (una recta) es 1+2x1+3x2=0 . La región azul representa el espacio en el que se encuentran todos los puntos para los que 1+2x1+3x2>0 y la región roja el de los puntos para los que 1+2x1+3x2<0 .

Ejemplo para caso de diagnóstico de cáncer utilizando imágenes

Los datos proceden de un estudio sobre diagnóstico del cáncer de mama por imagen. Mediante una punción con aguja fina se extrae una muestra del tejido sospechoso de la paciente. La muestra se tiñe para resaltar los núcleos de las células y se determinan los límites exactos de los núcleos. Las variables consideradas corresponden a distintos aspectos de la forma del núcleo. El fichero contiene un data.frame, llamado breast.cancer2, con 2 variables explicativas medidas en pacientes cuyos tumores fueron diagnosticados posteriormente como benignos o malignos y el factor y que toma los valores 0 o 1 en función de si la correspondiente fila corresponde a un tumor benigno o maligno respectivamente. Más información sobre los datos se puede encontrar en esta dirección. En el fichero original se considera un total de 30 variables explicativas. Hay 569 observaciones, de las que 357 corresponden a tumores benignos y 212 a tumores malignos.

Paquetes y datos

library(pacman)
p_load("MASS","e1071")
load(url('https://verso.mat.uam.es/~joser.berrendero/datos/practica-svm-io.RData'))
head(breast.cancer2)
##    x.smoothness x.concavepoints y
## 20      0.09779        0.047810 0
## 21      0.10750        0.031100 0
## 22      0.10240        0.020760 0
## 38      0.08983        0.029230 0
## 47      0.08600        0.005917 0
## 49      0.10310        0.027490 0

Representación gráfica de los datos

# Prepara los datos
x <- cbind(breast.cancer2$x.smoothness, breast.cancer2$x.concavepoints)
y <- breast.cancer2$y
n0 <- sum(y==0)
n1 <- sum(y==1)
# Para que los graficos queden mas bonitos (rojo = maligno, verde = benigno)
colores <- c(rep('green',n0),rep('red',n1))
pchn <- 21

# Diagrama de dispersion
plot(x, pch = pchn, bg = colores, xlab='smoothness', ylab='concavepoints')

SVM lineal

Para calcular la regla de clasificación SVM lineal con C=10 , se usa la función svm del paquete e1071. El primer argumento y~. indica que la variable y (que debe ser necesariamente un factor) se desea predecir en términos del resto de variables del fichero. La sintaxis es similar a la que utilizaríamos para ajustar un modelo lineal o un modelo de regresión logística. El segundo argumento indica el fichero en el que están las variables que vamos a usar. El argumento kernel corresponde al núcleo que representa el producto escalar que queremos utilizar. La opción linear corresponde a k(x,y)=x′y . El argumento cost determina la penalización que ponemos a los errores de clasificación. Con el fin de estimar la probabilidad de clasificar erróneamente una observación se puede utilizar validación cruzada, dividiendo la muestra en, por ejemplo, dos partes. Ello se consigue fijando cross=2. Finalmente, scale=FALSE se usa para usar los datos no estandarizados (por defecto, sí se estandarizan).

C <- 10
svm.lineal <- svm(y~., data=breast.cancer2, kernel='linear', cost=C, cross=2, scale=FALSE)
summary(svm.lineal)
## 
## Call:
## svm(formula = y ~ ., data = breast.cancer2, kernel = "linear", cost = C, 
##     cross = 2, scale = FALSE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  10 
## 
## Number of Support Vectors:  258
## 
##  ( 129 129 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  0 1
## 
## 2-fold cross-validation on training data:
## 
## Total Accuracy: 88.7522 
## Single Accuracies:
##  86.97183 90.52632

Hay 258 vectores soporte. Usando validación cruzada con la muestra dividida en dos partes se estima una probabilidad de acierto en la clasificación de aproximadamente el 88% . Podemos cambiar el parámetro de penalización para ver si estos valores aumentan o disminuyen.

C <- 10^3
svm.lineal <- svm(y~., data=breast.cancer2, kernel='linear', cost=C, cross=2, scale=FALSE)
summary(svm.lineal)
## 
## Call:
## svm(formula = y ~ ., data = breast.cancer2, kernel = "linear", cost = C, 
##     cross = 2, scale = FALSE)
## 
## 
## Parameters:
##    SVM-Type:  C-classification 
##  SVM-Kernel:  linear 
##        cost:  1000 
## 
## Number of Support Vectors:  128
## 
##  ( 64 64 )
## 
## 
## Number of Classes:  2 
## 
## Levels: 
##  0 1
## 
## 2-fold cross-validation on training data:
## 
## Total Accuracy: 91.3884 
## Single Accuracies:
##  92.25352 90.52632

Con toda esta información es posible calcular el hiperplano que da la la regla de clasificación $ w_0+w’x=0 $ es el valor contenido en svm.lineal.rho cambiado de signo, y $w=_{iS}_i x_i $ w=∑i∈Sαixi (con S el conjunto de índices de los vectores soporte) y representar gráficamente la regla resultante:

x.svm <- x[svm.lineal$index,]
w <- crossprod(x.svm, svm.lineal$coefs)
w0 <- svm.lineal$rho

plot(x, pch = pchn, bg = colores, xlab='smoothness', ylab='concavepoints')
abline(w0/w[2], -w[1]/w[2], lwd=2, col='blue')

Información complementaria: Matriz 3D (ejemplo de imagen RGB)