Problem z e1071 libsvm?

13

Mam zestaw danych z dwiema nakładającymi się klasami, po siedem punktów w każdej klasie, punkty są w przestrzeni dwuwymiarowej. W R i biegnę svmz e1071pakietu, aby zbudować oddzielną hiperpłaszczyznę dla tych klas. Używam następującego polecenia:

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

gdzie xzawiera moje punkty danych i yich etykiety. Polecenie zwraca obiekt svm, którego używam do obliczenia parametrów (wektor normalny) (przecięcie) hiperpłaszczyzny oddzielającej.bwb

Rysunek (a) poniżej pokazuje moje punkty i hiperpłaszczyznę zwróconą przez svmpolecenie (nazwijmy tę hiperpłaszczyznę optymalną). Niebieski punkt z symbolem O pokazuje początek przestrzeni, linie przerywane pokazują margines, kółka to punkty, które mają niezerowe (zmienne luzu).ξ

Rysunek (b) pokazuje inną hiperpłaszczyznę, która jest równoległą translacją optymalnej o 5 (b_new = b_optimal - 5). Nietrudno zauważyć, że dla tej hiperpłaszczyzny funkcja celu (która jest zminimalizowana przez klasyfikację C svm) będzie miała niższą wartość niż dla optymalnej hiperpłaszczyzny pokazanej na rysunku ( za). Czy to wygląda na problem z tą funkcją? A może gdzieś popełniłem błąd?

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

wprowadź opis zdjęcia tutaj

Poniżej znajduje się kod R, którego użyłem w tym eksperymencie.

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)
Lew
źródło
Czy dostosowałeś parametr kosztu?
Etienne Racine
Zauważ, że znacznik BUGS odnosi się do wnioskowania bayesowskiego przy użyciu próbkowania Gibbs, a nie problemów z oprogramowaniem. Usunąłem tag.
Sycorax mówi Przywróć Monikę

Odpowiedzi:

5

W libsvm FAQ jest wspomniane, że etykiety używane „wewnątrz” algorytmu mogą się różnić od twoich. Czasami odwróci to znak „cewek” modelu.

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

αnynwy

Zobacz pytanie „Dlaczego znak przewidywanych etykiet i wartości decyzji jest czasami odwracany?” Tutaj .

TonySuarez
źródło
4

Ten sam problem wystąpił przy użyciu LIBSVM w MATLAB. Aby to przetestować, stworzyłem bardzo prosty, dwuwymiarowy, liniowo rozdzielany zestaw danych, który został przetłumaczony wzdłuż jednej osi na około -100. Trening liniowego svm przy użyciu LIBSVM wytworzył hiperpłaszczyznę, której przechwytywanie wciąż znajdowało się dokładnie wokół zera (a więc wskaźnik błędów wynosił oczywiście 50%). Ujednolicenie danych (odjęcie średniej) pomogło, choć wynikowy svm nadal nie działał idealnie ... zakłopotany. Wygląda na to, że LIBSVM obraca hiperpłaszczyznę wokół osi bez jej translacji. Być może powinieneś spróbować odjąć średnią z danych, ale wydaje się dziwne, że LIBSVM zachowałby się w ten sposób. Być może czegoś nam brakuje.

Za to, co jest warte, wbudowana funkcja MATLAB svmtrainstworzyła klasyfikator ze 100% dokładnością, bez standaryzacji.

Dave
źródło