Problem mit e1071 libsvm?

13

Ich habe einen Datensatz mit zwei überlappenden Klassen, sieben Punkte in jeder Klasse, Punkte liegen im zweidimensionalen Raum. In R rufe ich svmdas e1071Paket auf, um eine separate Hyperebene für diese Klassen zu erstellen. Ich benutze den folgenden Befehl:

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

Wo xenthält meine Datenpunkte und yenthält ihre Beschriftungen. Der Befehl gibt ein svm-Objekt zurück, mit dem ich die Parameter w (normaler Vektor) und b (Achsenabschnitt) der trennenden Hyperebene berechne .

Abbildung (a) unten zeigt meine Punkte und die vom svmBefehl zurückgegebene Hyperebene (nennen wir diese Hyperebene die optimale). Der blaue Punkt mit dem Symbol O zeigt den Raum Ursprung zeigen gepunktete Linien Rand, eingekreist sind Punkte , die nicht Null haben (slack Variablen).ξ

Abbildung (b) zeigt eine weitere Hyperebene, bei der es sich um eine parallele Translation der optimalen um 5 handelt (b_new = b_optimal - 5). Es ist nicht schwer zu erkennen, dass für diese Hyperebene die Zielfunktion (die durch die C-Klassifikation svm minimiert wird) einen niedrigeren Wert hat als für die in Abbildung (1) gezeigte optimale Hyperebene. ein). Sieht es so aus, als gäbe es ein Problem mit dieser Funktion? Oder habe ich irgendwo einen Fehler gemacht?

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

Bildbeschreibung hier eingeben

Unten ist der R-Code, den ich in diesem Experiment verwendet habe.

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)
Löwe
quelle
Haben Sie den Kostenparameter angepasst?
Etienne Racine
Beachten Sie, dass sich das BUGS-Tag auf Bayes'sche Inferenz mit Gibbs-Sampling und nicht auf Softwareprobleme bezieht. Ich habe den Tag entfernt.
Sycorax sagt Reinstate Monica

Antworten:

5

In den libsvm-FAQ wird erwähnt, dass die im Algorithmus verwendeten Bezeichnungen von Ihren abweichen können. Dies kehrt manchmal das Vorzeichen der "Coefs" des Modells um.

y=[1,+1,+1,1,...]y+11

αnynwy

Siehe die Frage "Warum werden das Vorzeichen vorhergesagter Bezeichnungen und Entscheidungswerte manchmal umgekehrt?" hier .

TonySuarez
quelle
4

Ich habe das gleiche Problem mit LIBSVM in MATLAB ausgeführt. Um es zu testen, habe ich einen sehr einfachen, linear trennbaren 2D-Datensatz erstellt, der zufällig entlang einer Achse nach -100 verschoben wurde. Das Trainieren einer linearen SVM mit LIBSVM ergab eine Hyperebene, deren Achsenabschnitt immer noch bei Null lag (und die Fehlerrate betrug natürlich 50%). Das Standardisieren der Daten (Abziehen des Mittelwerts) hat geholfen, obwohl das resultierende SVM immer noch nicht perfekt funktioniert hat ... verwirrend. Es scheint, als würde LIBSVM die Hyperebene nur um die Achse drehen, ohne sie zu verschieben. Vielleicht sollten Sie versuchen, den Mittelwert von Ihren Daten zu subtrahieren, aber es scheint merkwürdig, dass sich LIBSVM so verhält. Vielleicht fehlt uns etwas.

Für das, was es wert ist, hat die eingebaute MATLAB-Funktion svmtraineinen Klassifikator mit 100% Genauigkeit ohne Standardisierung erzeugt.

Dave
quelle