Nombre: Andrés Noboa
Cargamos las librerias
library(ggplot2)
Cargamos los data representantes de grupos que no son linealmente
separables.
set.seed(10111)
coordinate <- matrix(rnorm(40), 20, 2)
colnames(coordinate) <- c("x1","x2")
y <- c(rep(-1,10), rep(1,10))
coordinate[y == 1, ] <- coordinate[y == 1, ] + 1
df <- data.frame(coordinate, y)
ggplot(data = df, aes(x = x1, y = x2, color = as.factor(y))) +
geom_point(size = 6) +
theme_bw() +
theme(legend.position = "none")

la funcion svm(), nos indica automáticamente si se trata
de un problema de clasificación, la variable respuesta es de tipo
factor, o de regresión, la variable respuesta es tipo numérico
df$y <- as.factor(df$y)
modelo_svm <- svm(formula = y ~ x1 + x2, data = df, kernel = "linear",
cost = 10, scale = FALSE)
El summary del modelo muestra que hay un total de 6 vectores soporte,
3 pertenecen a una clase y 3 a la otra.
summary(modelo_svm)
Call:
svm(formula = y ~ x1 + x2, data = df, kernel = "linear", cost = 10, scale = FALSE)
Parameters:
SVM-Type: C-classification
SVM-Kernel: linear
cost: 10
Number of Support Vectors: 6
( 3 3 )
Number of Classes: 2
Levels:
-1 1
Empleando la función plot() con un objeto de tipo svm junto con las
observaciones de entrenamiento, se obtiene una representación del límite
de decisión:
plot(modelo_svm, df)

Alternativa basada en ggplot2 para obtener una representación de los
resultados de svm() :
# range de los predictores
range_x1 <- range(data$x1)
range_x2 <- range(data$x2)
# Interpolación de puntos
new_x1 <- seq(from = range_x1[1], to = range_x1[2], length = 75)
new_x2 <- seq(from = range_x2[1], to = range_x2[2], length = 75)
nuevos_puntos <- expand.grid(x1 = new_x1, x2 = new_x2)
# Predicción según el modelo
predicciones <- predict(object = modelo_svm, newdata = nuevos_puntos)
# Se almacenan los puntos predichos para dar color a las regiones
color_regiones <- data.frame(nuevos_puntos, y = predicciones)
# Para extraer la ecuación del hiperplano y del margen es necesario aplicar
# algebra lineal.
beta <- drop(t(modelo_svm$coefs) %*% as.matrix(data[,c("x1","x2")])[modelo_svm$index,])
beta0 <- modelo_svm$rho
ggplot() +
# Representación de las 2 regiones empleando los puntos y coloreándolos
# según la clase predicha por el modelo
geom_point(data = color_regiones, aes(x = x1, y = x2, color = as.factor(y)),
size = 0.5) +
# Se añaden las observaciones
geom_point(data = data, aes(x = x1, y = x2, color = as.factor(y)),
size = 6) +
# Se identifican aquellas observaciones que son vectores soporte del modelo
geom_point(data = data[modelo_svm$index, ],
aes(x = x1, y = x2, color = as.factor(y)),
shape = 21, colour = "black",
size = 6) +
# Se añaden las rectas del hiperplano y los márgenes
geom_abline(intercept = beta0/beta[2], slope = -beta[1]/beta[2]) +
geom_abline(intercept = (beta0 - 1)/beta[2], slope = -beta[1]/beta[2],
linetype = "dashed") +
geom_abline(intercept = (beta0 + 1)/beta[2], slope = -beta[1]/beta[2],
linetype = "dashed") +
theme_bw() +
theme(legend.position = "none")

Podemos realizar cross-validation mediante el paquete
e1071 de R, con tune() podemos especificar un
10-fold cross validation
set.seed(1) # semilla en 1
svm_cv <- tune("svm", y ~ x1 + x2, data = df,
kernel = 'linear',
ranges = list(cost = c(0.001, 0.01, 0.1, 1, 5, 10, 20, 50, 100,
150, 200)))
summary(svm_cv)
Parameter tuning of ‘svm’:
- sampling method: 10-fold cross validation
- best parameters:
- best performance: 0.1
- Detailed performance results:
NA
Gráfico del error de clasificación vs hiperparámetro C
ggplot(data = svm_cv$performances, aes(x = cost, y = error)) +
geom_line() +
geom_point() +
labs(title = "Error de clasificación vs hyperparameter C") +
theme_bw()

Obtenemos el mejor modelo de los hiperparameters
Test dataset simulado
# Datos de test simulados
set.seed(19)
coordenadas <- matrix(rnorm(40), 20, 2)
colnames(coordenadas) <- c("x1","x2")
y <- sample(c(-1,1), 20, rep = TRUE)
coordenadas[y == 1, ] <- coordenadas[y == 1, ] + 1
test <- data.frame(coordenadas, y)
Predicciones
paste("Error de test:", 100*mean(test$y != predicciones),"%")
[1] "Error de test: 15 %"
Matriz de confusion de las predicciones
table(predicción = predicciones, valor_real = test$y)
valor_real
predicción -1 1
-1 10 0
1 3 7
LS0tCnRpdGxlOiAiTcOhcXVpbmFzIGRlIFZlY3RvciBTb3BvcnRlIChTdXBwb3J0IFZlY3RvciBNYWNoaW5lcywgU1ZNcykiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KCk5vbWJyZTogQW5kcsOpcyBOb2JvYSAKCkNhcmdhbW9zIGxhcyBsaWJyZXJpYXMgCmBgYHtyfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkoZTEwNzEpCgpgYGAKCkNhcmdhbW9zIGxvcyBkYXRhIHJlcHJlc2VudGFudGVzIGRlIGdydXBvcyBxdWUgbm8gc29uIGxpbmVhbG1lbnRlIHNlcGFyYWJsZXMuCgpgYGB7cn0Kc2V0LnNlZWQoMTAxMTEpCmNvb3JkaW5hdGUgPC0gbWF0cml4KHJub3JtKDQwKSwgMjAsIDIpCmNvbG5hbWVzKGNvb3JkaW5hdGUpIDwtIGMoIngxIiwieDIiKQp5IDwtIGMocmVwKC0xLDEwKSwgcmVwKDEsMTApKQpjb29yZGluYXRlW3kgPT0gMSwgXSA8LSBjb29yZGluYXRlW3kgPT0gMSwgXSArIDEKZGYgPC0gZGF0YS5mcmFtZShjb29yZGluYXRlLCB5KQpnZ3Bsb3QoZGF0YSA9IGRmLCBhZXMoeCA9IHgxLCB5ID0geDIsIGNvbG9yID0gYXMuZmFjdG9yKHkpKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDYpICsKICB0aGVtZV9idygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCgpgYGAKbGEgZnVuY2lvbiBgc3ZtKClgLCBub3MgaW5kaWNhICBhdXRvbcOhdGljYW1lbnRlIHNpIHNlIHRyYXRhIGRlIHVuIHByb2JsZW1hIGRlIGNsYXNpZmljYWNpw7NuLCBsYSB2YXJpYWJsZSByZXNwdWVzdGEgZXMgZGUgdGlwbyBmYWN0b3IsIG8gZGUgcmVncmVzacOzbiwgbGEgdmFyaWFibGUgcmVzcHVlc3RhIGVzIHRpcG8gbnVtw6lyaWNvCgpgYGB7cn0KZGYkeSA8LSBhcy5mYWN0b3IoZGYkeSkKCm1vZGVsb19zdm0gPC0gc3ZtKGZvcm11bGEgPSB5IH4geDEgKyB4MiwgZGF0YSA9IGRmLCBrZXJuZWwgPSAibGluZWFyIiwKICAgICAgICAgICAgICAgICAgY29zdCA9IDEwLCBzY2FsZSA9IEZBTFNFKQpgYGAKCgpFbCBzdW1tYXJ5IGRlbCBtb2RlbG8gbXVlc3RyYSBxdWUgaGF5IHVuIHRvdGFsIGRlIDYgdmVjdG9yZXMgc29wb3J0ZSwgMyBwZXJ0ZW5lY2VuIGEgdW5hIGNsYXNlIHkgMyBhIGxhIG90cmEuCmBgYHtyfQpzdW1tYXJ5KG1vZGVsb19zdm0pCgpgYGAKCkVtcGxlYW5kbyBsYSBmdW5jacOzbiBwbG90KCkgY29uIHVuIG9iamV0byBkZSB0aXBvIHN2bSBqdW50byBjb24gbGFzIG9ic2VydmFjaW9uZXMgZGUgZW50cmVuYW1pZW50bywgc2Ugb2J0aWVuZSB1bmEgcmVwcmVzZW50YWNpw7NuIGRlbCBsw61taXRlIGRlIGRlY2lzacOzbjoKCmBgYHtyfQpwbG90KG1vZGVsb19zdm0sIGRmKQoKYGBgCkFsdGVybmF0aXZhIGJhc2FkYSBlbiBnZ3Bsb3QyIHBhcmEgb2J0ZW5lciB1bmEgcmVwcmVzZW50YWNpw7NuIGRlIGxvcyByZXN1bHRhZG9zIGRlIHN2bSgpIDoKCmBgYHtyfQojIHJhbmdlIGRlIGxvcyBwcmVkaWN0b3JlcwpyYW5nZV94MSA8LSByYW5nZShkYXRhJHgxKQpyYW5nZV94MiA8LSByYW5nZShkYXRhJHgyKQoKbmV3X3gxIDwtIHNlcShmcm9tID0gcmFuZ2VfeDFbMV0sIHRvID0gcmFuZ2VfeDFbMl0sIGxlbmd0aCA9IDc1KQpuZXdfeDIgPC0gc2VxKGZyb20gPSByYW5nZV94MlsxXSwgdG8gPSByYW5nZV94MlsyXSwgbGVuZ3RoID0gNzUpCm51ZXZvc19wdW50b3MgPC0gZXhwYW5kLmdyaWQoeDEgPSBuZXdfeDEsIHgyID0gbmV3X3gyKQoKIyBQcmVkaWNjacOzbiBzZWfDum4gZWwgbW9kZWxvCnByZWRpY2Npb25lcyA8LSBwcmVkaWN0KG9iamVjdCA9IG1vZGVsb19zdm0sIG5ld2RhdGEgPSBudWV2b3NfcHVudG9zKQoKY29sb3JfcmVnaW9uZXMgPC0gZGF0YS5mcmFtZShudWV2b3NfcHVudG9zLCB5ID0gcHJlZGljY2lvbmVzKQoKIyBFeHRyYXllbmRvIGxhIGVjIGRlbCBoaXBlcnBsYW5vCmJldGEgPC0gZHJvcCh0KG1vZGVsb19zdm0kY29lZnMpICUqJSBhcy5tYXRyaXgoZGF0YVssYygieDEiLCJ4MiIpXSlbbW9kZWxvX3N2bSRpbmRleCxdKQpiZXRhMCA8LSBtb2RlbG9fc3ZtJHJobwoKCmdncGxvdCgpICsKICBnZW9tX3BvaW50KGRhdGEgPSBjb2xvcl9yZWdpb25lcywgYWVzKHggPSB4MSwgeSA9IHgyLCBjb2xvciA9IGFzLmZhY3Rvcih5KSksCiAgICAgICAgICAgICBzaXplID0gMC41KSArCiAgIyBTZSBhw7FhZGVuIGxhcyBvYnNlcnZhY2lvbmVzCiAgZ2VvbV9wb2ludChkYXRhID0gZGF0YSwgYWVzKHggPSB4MSwgeSA9IHgyLCBjb2xvciA9IGFzLmZhY3Rvcih5KSksCiAgICAgICAgICAgICBzaXplID0gNikgKwogICMgU2UgaWRlbnRpZmljYW4gYXF1ZWxsYXMgb2JzZXJ2YWNpb25lcyBxdWUgc29uIHZlY3RvcmVzIHNvcG9ydGUgZGVsIG1vZGVsbwogIGdlb21fcG9pbnQoZGF0YSA9IGRhdGFbbW9kZWxvX3N2bSRpbmRleCwgXSwKICAgICAgICAgICAgIGFlcyh4ID0geDEsIHkgPSB4MiwgY29sb3IgPSBhcy5mYWN0b3IoeSkpLAogICAgICAgICAgICAgc2hhcGUgPSAyMSwgY29sb3VyID0gImJsYWNrIiwKICAgICAgICAgICAgIHNpemUgPSA2KSArCiAgIyBTZSBhw7FhZGVuIGxhcyByZWN0YXMgZGVsIGhpcGVycGxhbm8geSBsb3MgbcOhcmdlbmVzCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gYmV0YTAvYmV0YVsyXSwgc2xvcGUgPSAtYmV0YVsxXS9iZXRhWzJdKSArCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gKGJldGEwIC0gMSkvYmV0YVsyXSwgc2xvcGUgPSAtYmV0YVsxXS9iZXRhWzJdLAogICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsgICAgCiAgZ2VvbV9hYmxpbmUoaW50ZXJjZXB0ID0gKGJldGEwICsgMSkvYmV0YVsyXSwgc2xvcGUgPSAtYmV0YVsxXS9iZXRhWzJdLAogICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICB0aGVtZV9idygpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpCmBgYAoKClBvZGVtb3MgcmVhbGl6YXIgYGNyb3NzLXZhbGlkYXRpb25gIG1lZGlhbnRlIGVsIHBhcXVldGUgYGUxMDcxYCBkZSBSLCBjb24gYHR1bmUoKWAgcG9kZW1vcyBlc3BlY2lmaWNhciB1biAxMC1mb2xkIGNyb3NzIHZhbGlkYXRpb24KYGBge3J9CnNldC5zZWVkKDEpICMgc2VtaWxsYSBlbiAxCnN2bV9jdiA8LSB0dW5lKCJzdm0iLCB5IH4geDEgKyB4MiwgZGF0YSA9IGRmLAogICAgICAgICAgICAgICBrZXJuZWwgPSAnbGluZWFyJywKICAgICAgICAgICAgICAgcmFuZ2VzID0gbGlzdChjb3N0ID0gYygwLjAwMSwgMC4wMSwgMC4xLCAxLCA1LCAxMCwgMjAsIDUwLCAxMDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMTUwLCAyMDApKSkKc3VtbWFyeShzdm1fY3YpCmBgYAoKCgoKIyMjIEdyw6FmaWNvIGRlbCBlcnJvciBkZSBjbGFzaWZpY2FjacOzbiB2cyBoaXBlcnBhcsOhbWV0cm8gQyAKYGBge3J9CmdncGxvdChkYXRhID0gc3ZtX2N2JHBlcmZvcm1hbmNlcywgYWVzKHggPSBjb3N0LCB5ID0gZXJyb3IpKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoKSArCiAgbGFicyh0aXRsZSA9ICJFcnJvciBkZSBjbGFzaWZpY2FjacOzbiB2cyBoeXBlcnBhcmFtZXRlciBDIikgKwogIHRoZW1lX2J3KCkKYGBgCk9idGVuZW1vcyBlbCBtZWpvciBtb2RlbG8gZGUgbG9zIGhpcGVycGFyYW1ldGVycwoKYGBge3J9CmJlc3RfbW9kZWwgPC0gc3ZtX2N2JGJlc3QubW9kZWwKYGBgCgpUZXN0IGRhdGFzZXQgc2ltdWxhZG8KYGBge3J9CnNldC5zZWVkKDE5KQpjb29yZGVuYWRhcyA8LSBtYXRyaXgocm5vcm0oNDApLCAyMCwgMikKY29sbmFtZXMoY29vcmRlbmFkYXMpIDwtIGMoIngxIiwieDIiKQp5IDwtIHNhbXBsZShjKC0xLDEpLCAyMCwgcmVwID0gVFJVRSkKY29vcmRlbmFkYXNbeSA9PSAxLCBdIDwtIGNvb3JkZW5hZGFzW3kgPT0gMSwgXSArIDEKdGVzdCA8LSBkYXRhLmZyYW1lKGNvb3JkZW5hZGFzLCB5KQpgYGAKCiMjIFByZWRpY2Npb25lcyAKYGBge3J9CnByZWRpY2Npb25lcyA8LSBwcmVkaWN0KG9iamVjdCA9IGJlc3RfbW9kZWwsIHRlc3QpCnBhc3RlKCJFcnJvciBkZSB0ZXN0OiIsIDEwMCptZWFuKHRlc3QkeSAhPSBwcmVkaWNjaW9uZXMpLCIlIikKYGBgCgojIyBNYXRyaXogZGUgY29uZnVzaW9uIGRlICBsYXMgcHJlZGljY2lvbmVzCmBgYHtyfQp0YWJsZShwcmVkaWNjacOzbiA9IHByZWRpY2Npb25lcywgdmFsb3JfcmVhbCA9IHRlc3QkeSkKYGBgCgo=