twinsvm fits twin support vector machines and provides a
standard C-SVC SVM baseline for comparison. Binary fits use two-class
factors: level 1 is class B, level 2 is class A. Multiclass fits use
one-vs-one majority voting, with ties resolved by the first factor
level.
For a linear twin SVM, the two fitted planes are drawn as dashed lines.
cv <- cv_tsvm(
dat$x,
dat$y,
c1_grid = c(0.1, 1),
c2_grid = c(0.1, 1),
gamma_grid = c(1, 2),
kernel = "rbf",
k = 3
)
cv$best_params
#> $c1
#> [1] 1
#>
#> $c2
#> [1] 1
#>
#> $gamma
#> [1] 1
plot(cv)set.seed(4)
x3 <- rbind(
matrix(rnorm(30, -2, 0.25), ncol = 2),
cbind(rnorm(15, 2, 0.25), rnorm(15, -2, 0.25)),
matrix(rnorm(30, 2, 0.25), ncol = 2)
)
y3 <- factor(rep(c("alpha", "beta", "gamma"), each = 15))
multi <- tsvm(x3, y3, kernel = "linear")
head(predict(multi, x3))
#> [1] alpha alpha alpha alpha alpha alpha
#> Levels: alpha beta gamma
head(predict(multi, x3, type = "votes"))
#> alpha beta gamma
#> [1,] 2 1 0
#> [2,] 2 1 0
#> [3,] 2 1 0
#> [4,] 2 1 0
#> [5,] 2 1 0
#> [6,] 2 1 0
confusion(multi, x3, y3)
#> $table
#> predicted
#> truth alpha beta gamma
#> alpha 15 0 0
#> beta 0 15 0
#> gamma 0 0 15
#>
#> $accuracy
#> [1] 1timing <- data.frame(
n = c(40, 80, 120),
tsvm_seconds = NA_real_,
svms_seconds = NA_real_
)
for (i in seq_len(nrow(timing))) {
set.seed(i)
d <- gen_moons(timing$n[i], noise = 0.12)
timing$tsvm_seconds[i] <- system.time(tsvm(d$x, d$y, kernel = "rbf", gamma = 2))[["elapsed"]]
timing$svms_seconds[i] <- system.time(svms(d$x, d$y, kernel = "rbf", gamma = 2))[["elapsed"]]
}
timing
#> n tsvm_seconds svms_seconds
#> 1 40 0 0.00
#> 2 80 0 0.00
#> 3 120 0 0.01The timing table is generated on the machine running this vignette.
Kernel twin-SVM forms invert an (n + 1) matrix, so they are
meant for small to moderate data.
The same data can be shown through the three fitted classifiers in one row.
set.seed(2)
small <- gen_moons(60, noise = 0.1)
compare_methods(small$x, small$y, gamma = 1, c1 = 0.2, c2 = 0.2, cost = 1)morph_boundary() returns a gganimate
object. Rendering is left to the user so package examples stay fast.
The standard SVM baseline is tested against e1071, which
is backed by LIBSVM. There is no existing R twin-SVM package to match
against, so twin-SVM tests validate plane-distance behavior, nonlinear
kernel improvement, and agreement between the least-squares and original
QP formulations. The algorithms follow Jayadeva, Khemchandani, and
Chandra (2007) and Kumar and Gopal (2009).