Luigi Marongiu
2019-May-08 08:25 UTC
[R] Extract hyperplane from kernlab's Support Vector Machine model
Dear all, I would like to extract an hyperplance froma SVM model generated with the kernlab package. The model I have made is non-linear and I am looking to plot the line that separates the two groups in order to draw custom plots with more control. I understand that I should use a contour plot but I do not understand how to implement the function. I will show the process I have done with the example reported in here (https://www.datacamp.com/community/tutorials/support-vector-machines-r); I had to re-arrange the data to pass from e1071 to kernlab. Essentially it all works until I reach the contour part. How can I add a line that represents the boundaries between the red and blue dots? In the following working example, this boundary (the hyperplane) is represented roughly by the green line; in the real case, it should be a convoluted curve. Also, I reckon countour should have an add=TRUE option in order to add it to an existing plot. Thank you>>>set.seed(10111) library(kernlab) x = matrix(rnorm(40), 20, 2) y = rep(c(-1, 1), c(10, 10)) x[y == 1,] = x[y == 1,] + 1 plot(x, col = y + 3, pch = 19) dat = data.frame(x, y = as.factor(y)) MAXx1 = max(dat$X1) MAXx2 = max(dat$X2) MINx1 = min(dat$X1) MINx2 = min(dat$X2) svmfit = ksvm(y ~ X1+X2, data = dat, type = "C-svc", kernel = "vanilladot", kpar = "automatic", C = 10, prob.model = TRUE) print(svmfit) plot(svmfit, data = dat) # make own plot make.grid = function(x, n = 75) { grange = apply(x, 2, range) x1 = seq(from = grange[1,1], to = grange[2,1], length = n) x2 = seq(from = grange[1,2], to = grange[2,2], length = n) expand.grid(X1 = x1, X2 = x2) } M = matrix(c(dat$X1, dat$X2), ncol = 2, byrow=FALSE) xgrid = make.grid(M) xgrid[1:10,] ygrid = predict(svmfit, xgrid) plot(xgrid, col = c("red","blue")[as.numeric(ygrid)], pch = 20, cex = .2, xlim=c(MINx1, MAXx1), ylim = c(MINx2, MAXx2)) points(dat[dat[, "y"] == -1,], col = "red", pch = 19) points(dat[dat[, "y"] == 1,], col = "blue", pch = 18, cex = 1.5) abline(a = 0.9, b = -0.65, col = "green", lwd = 2) # here is where I am lost contour(dat[dat[, "y"] == -1,]$X1, dat[dat[, "y"] == 1,]$X2, dat[dat[, "y"] == -1,]$y) # Error in contour.default(dat[dat[, "y"] == -1, ]$X1, dat[dat[, "y"] == : # increasing 'x' and 'y' values expected M_ord = M[order(M[,1], M[,2],decreasing=TRUE),] contour(M[, 1], M[, 2], dat[dat[, "y"] == -1,]$y) # Error in contour.default(M[, 1], M[, 2], dat[dat[, "y"] == -1, ]$y) : # increasing 'x' and 'y' values expected M_ord = M[order(M[,1], M[,2],decreasing=FALSE),] contour(M[, 1], M[, 2], dat[dat[, "y"] == -1,]$y) # Error in contour.default(M[, 1], M[, 2], dat[dat[, "y"] == -1, ]$y) : # increasing 'x' and 'y' values expected -- Best regards, Luigi