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 svm
depuis le e1071
package 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)
où x
contient mes points de données et y
contient 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.b
La figure (a) ci-dessous montre mes points et l'hyperplan renvoyé par la svm
commande (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?
svm
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)
Réponses:
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 +1 −1
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αnyn w y
Voir la question "Pourquoi le signe des étiquettes prédites et des valeurs de décision est-il parfois inversé?" ici .
la source
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
svmtrain
produit un classificateur avec une précision de 100%, sans standardisation.la source