13 votos

¿Problemas con e1071 libsvm?

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 ejecutando svm de la e1071 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 x contiene mis puntos de datos y y contiene sus etiquetas. El comando devuelve un objeto svm, que utilizo para calcular los parámetros $w$ (vector normal) y $b$ (intercepción) del hiperplano de separación.

La figura (a) muestra mis puntos y el hiperplano devuelto por el svm (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, los círculos son los puntos que tienen $\xi$ (variables de holgura).

La figura (b) muestra otro hiperplano, que es una traslación paralela del óptimo en 5 (b_nuevo = b_óptimo - 5). No es difícil ver que para este hiperplano la función objetivo $$ 0.5||w||^2 + cost \sum \xi_i $$ (que es minimizado por la clasificación C svm) tendrá un valor menor que para el hiperplano óptimo mostrado en la figura (a). Entonces, ¿parece que hay un problema con este svm ¿función? ¿O he cometido un error en alguna parte?

enter image description here

A continuación se muestra el código R que he utilizado 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)

5voto

Umber Ferrule Puntos 1453

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

Por ejemplo, si tiene etiquetas $y=[-1,+1,+1,-1,...]$ , entonces la primera etiqueta en $y$ que es "-1", se clasificará como $+1$ para ejecutar libsvm y, obviamente, su "+1" será clasificado como $-1$ dentro del algoritmo.

Y recuerda que los coefs en el modelo svm devuelto son efectivamente $\alpha_n\,y_n$ y así su calculado $w$ vector se verá afectado debido a la reversión del signo del $y$ 's.

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

4voto

hhh Puntos 208

Me he encontrado con el mismo problema usando LIBSVM en MATLAB. Para probarlo, creé un conjunto de datos muy simple, linealmente separable en 2D, que resultó ser trasladado a lo largo de un eje hasta alrededor de -100. El entrenamiento de un svm lineal usando LIBSVM produjo un hiperplano cuya intercepción estaba todavía alrededor de cero (y así la tasa de error era del 50%, naturalmente). Estandarizar los datos (restando la media) ayudó, aunque el svm resultante seguía sin funcionar a la perfección... desconcertante. Parece que LIBSVM sólo gira el hiperplano sobre el eje sin traducirlo. Tal vez deberías intentar restar la media de tus datos, pero parece impar que LIBSVM se comporte así. Tal vez nos estemos perdiendo algo.

Por si sirve de algo, la función integrada de MATLAB svmtrain produjo un clasificador con una precisión del 100%, sin estandarización.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X