Un problème avec e1071 libsvm?

13

J'ai un ensemble de données avec deux classes qui se chevauchent, sept points dans chaque classe, les points sont dans un espace à deux dimensions. Dans R, et je cours svmdepuis le e1071package pour construire un hyperplan de séparation pour ces classes. J'utilise la commande suivante:

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

xcontient mes points de données et ycontient leurs étiquettes. La commande retourne un objet svm, que j'utilise pour calculer les paramètres (vecteur normal) et (interception) de l'hyperplan de séparation.bwb

La figure (a) ci-dessous montre mes points et l'hyperplan renvoyé par la svmcommande (appelons cet hyperplan l'optimal). Le point bleu avec le symbole O montre l'origine de l'espace, les lignes pointillées montrent la marge, entourés de points qui ont un non nul (variables de mou).ξ

La figure (b) montre un autre hyperplan, qui est une translation parallèle de l'optimal par 5 (b_new = b_optimal - 5). Il n'est pas difficile de voir que pour cet hyperplan la fonction objectif (qui est minimisée par la classification C svm) aura une valeur inférieure à celle de l'hyperplan optimal illustré sur la figure ( une). Cela ressemble-t-il à un problème avec cette fonction? Ou ai-je fait une erreur quelque part?

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

entrez la description de l'image ici

Voici le code R que j'ai utilisé dans cette expérience.

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)
Leo
la source
Avez-vous réglé le paramètre de coût?
Etienne Racine
Notez que la balise BUGS fait référence à l'inférence bayésienne utilisant l'échantillonnage de Gibbs, et non à des problèmes logiciels. J'ai supprimé la balise.
Sycorax dit Réintégrer Monica le

Réponses:

5

Dans la FAQ libsvm, il est mentionné que les étiquettes utilisées "à l'intérieur" de l'algorithme peuvent être différentes des vôtres. Cela inversera parfois le signe des «coefs» du modèle.

Par exemple, si vous aviez des étiquettes , la première étiquette de , qui est "-1", sera classée comme pour l'exécution de libsvm et, évidemment, votre "+1" sera classé comme à l'intérieur de l'algorithme.y + 1 - 1y=[1,+1,+1,1,...]y+11

Et rappelez-vous que les coefs dans le modèle svm retourné sont en effet et donc votre vecteur calculé sera affecté en raison de la réversion du signe des . w yαnynwy

Voir la question "Pourquoi le signe des étiquettes prédites et des valeurs de décision est-il parfois inversé?" ici .

TonySuarez
la source
4

J'ai rencontré le même problème en utilisant LIBSVM dans MATLAB. Pour le tester, j'ai créé un ensemble de données 2D séparable linéairement très simple qui s'est avéré être traduit le long d'un axe jusqu'à environ -100. La formation d'un svm linéaire à l'aide de LIBSVM a produit un hyperplan dont l'interception était toujours juste autour de zéro (et donc le taux d'erreur était de 50%, naturellement). La standardisation des données (soustraction de la moyenne) a aidé, bien que le svm résultant n'ait toujours pas fonctionné parfaitement ... perplexe. Il semble que LIBSVM fasse uniquement tourner l'hyperplan autour de l'axe sans le translater. Vous devriez peut-être essayer de soustraire la moyenne de vos données, mais il semble étrange que LIBSVM se comporte de cette façon. Peut-être qu'il nous manque quelque chose.

Pour ce qu'elle vaut, la fonction MATLAB intégrée a svmtrainproduit un classificateur avec une précision de 100%, sans standardisation.

Dave
la source