¿Problema con e1071 libsvm?

13

Tengo un conjunto de datos con dos clases superpuestas, siete puntos en cada clase, los puntos están en un espacio bidimensional. En R, y estoy corriendo svmdesde el e1071paquete para construir un hiperplano de separación para estas clases. Estoy usando el siguiente comando:

svm(x, y, scale = FALSE, type = 'C-classification', kernel = 'linear', cost = 50000)

donde xcontiene mis puntos de datos y ycontiene sus etiquetas. El comando devuelve un objeto svm, que uso para calcular los parámetros (vector normal) (intercepción) del hiperplano de separación.bwb

La figura (a) a continuación muestra mis puntos y el hiperplano devuelto por el svmcomando (llamemos a este hiperplano el óptimo). El punto azul con el símbolo O muestra el origen del espacio, las líneas punteadas muestran el margen, encerrados en un círculo son puntos que no son cero (variables de holgura).ξ

La Figura (b) muestra otro hiperplano, que es una traducción paralela del óptimo por 5 (b_new = b_optimal - 5). No es difícil ver que para este hiperplano la función objetivo (que se minimiza mediante la clasificación C svm) tendrá un valor menor que para el hiperplano óptimo que se muestra en la figura ( un). Entonces, ¿parece que hay un problema con esta función? ¿O cometí un error en alguna parte?

0.5||w||2+costξi
svm

ingrese la descripción de la imagen aquí

A continuación se muestra el código R que utilicé en este experimento.

library(e1071)

get_obj_func_info <- function(w, b, c_par, x, y) {
    xi <- rep(0, nrow(x))

    for (i in 1:nrow(x)) {
        xi[i] <- 1 - as.numeric(as.character(y[i]))*(sum(w*x[i,]) + b)
        if (xi[i] < 0) xi[i] <- 0
    }

    return(list(obj_func_value = 0.5*sqrt(sum(w * w)) + c_par*sum(xi), 
                    sum_xi = sum(xi), xi = xi))
}

x <- structure(c(41.8226593092589, 56.1773406907411, 63.3546813814822, 
66.4912298720281, 72.1002963174962, 77.649309469458, 29.0963054665561, 
38.6260575252066, 44.2351239706747, 53.7648760293253, 31.5087701279719, 
24.3314294372308, 21.9189647758150, 68.9036945334439, 26.2543850639859, 
43.7456149360141, 52.4912298720281, 20.6453186185178, 45.313889181287, 
29.7830021158501, 33.0396571934088, 17.9008386892901, 42.5694092520593, 
27.4305907479407, 49.3546813814822, 40.6090664454681, 24.2940422573947, 
36.9603428065912), .Dim = c(14L, 2L))

y <- structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = c("-1", "1"), class = "factor")

a <- svm(x, y, scale = FALSE, type = 'C-classification', kernel = 'linear', cost = 50000)

w <- t(a$coefs) %*% a$SV;
b <- -a$rho;

obj_func_str1 <- get_obj_func_info(w, b, 50000, x, y)
obj_func_str2 <- get_obj_func_info(w, b - 5, 50000, x, y)
León
fuente
¿Ajustó el parámetro de costo?
Etienne Racine
Tenga en cuenta que la etiqueta BUGS hace referencia a la inferencia bayesiana que usa muestreo de Gibbs, no a problemas de software. He quitado la etiqueta.
Sycorax dice Reinstate Monica

Respuestas:

5

En las preguntas frecuentes de libsvm se menciona que las etiquetas utilizadas "dentro" del algoritmo pueden ser diferentes a las suyas. Esto a veces revertirá el signo de los "coefs" del modelo.

Por ejemplo, si tenía etiquetas , la primera etiqueta en , que es "-1", se clasificará como para ejecutar libsvm y, obviamente, su "+1" se clasificará como dentro del algoritmo.y + 1 - 1y=[1,+1,+1,1,...]y+11

Y recuerde que los coeficientes en el modelo svm devuelto son de hecho y, por lo tanto, su vector calculado se verá afectado debido a la reversión del signo de los 's. w yαnynwy

Consulte la pregunta "¿Por qué a veces se invierte el signo de las etiquetas predichas y los valores de decisión?" Aquí .

TonySuarez
fuente
4

Me he encontrado con el mismo problema usando LIBSVM en MATLAB. Para probarlo, creé un conjunto de datos 2D linealmente separable muy simple que resultó ser traducido a lo largo de un eje a alrededor de -100. El entrenamiento de un svm lineal usando LIBSVM produjo un hiperplano cuya intersección todavía estaba alrededor de cero (y, por lo tanto, la tasa de error fue del 50%, naturalmente). La estandarización de los datos (restando la media) ayudó, aunque la svm resultante todavía no funcionó perfectamente ... desconcertante. Parece que LIBSVM solo gira el hiperplano alrededor del eje sin traducirlo. Quizás debería intentar restar la media de sus datos, pero parece extraño que LIBSVM se comporte de esta manera. Quizás nos estamos perdiendo algo.

Por lo que vale, la función MATLAB incorporada svmtrainprodujo un clasificador con una precisión del 100%, sin estandarización.

Dave
fuente