Problema com e1071 libsvm?

13

Eu tenho um conjunto de dados com duas classes sobrepostas, sete pontos em cada classe, os pontos estão no espaço bidimensional. Em R, e estou executando svmo e1071pacote para criar um hiperplano de separação para essas classes. Estou usando o seguinte comando:

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

onde xcontém meus pontos de dados e yseus rótulos. O comando retorna um objeto svm, que eu uso para calcular os parâmetros (vetor normal) eb (interceptação) do hiperplano de separação.Wb

A figura (a) abaixo mostra meus pontos e o hiperplano retornado pelo svmcomando (vamos chamar esse hiperplano de ideal). O ponto azul com o símbolo O mostra a origem do espaço, as linhas pontilhadas mostram a margem, circuladas são pontos com diferente de zero (variáveis ​​de folga).ξ

A Figura (b) mostra outro hiperplano, que é uma tradução paralela da ideal por 5 (b_new = b_optimal - 5). Não é difícil perceber que, para este hiperplano, a função objetivo (o que é minimizado por SVM C-classificação) terá o valor mais baixo do que para o hiperplana óptima mostrado na figura (a). Então, parece que há um problema com esta função? Ou cometi um erro em algum lugar?

0,5||W||2+costξEu
svm

insira a descrição da imagem aqui

Abaixo está o código R que usei neste 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)
Leo
fonte
Você ajustou o parâmetro cost?
precisa saber é o seguinte
Observe que a etiqueta BUGS refere-se à inferência bayesiana usando a amostragem de Gibbs, não a problemas de software. Eu removi a tag.
Sycorax diz Restabelecer Monica

Respostas:

5

Na FAQ da libsvm é mencionado que os rótulos usados ​​"dentro" do algoritmo podem ser diferentes dos seus. Isso às vezes reverterá o sinal dos "coefs" do modelo.

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

αnynWy

Consulte a pergunta "Por que o sinal dos rótulos e valores de decisão previstos às vezes é revertido?" aqui .

TonySuarez
fonte
4

Corri para o mesmo problema usando LIBSVM no MATLAB. Para testá-lo, criei um conjunto de dados 2D linearmente separável, muito simples, que foi traduzido ao longo de um eixo para cerca de -100. Treinar um svm linear usando LIBSVM produziu um hiperplano cuja interceptação ainda estava próxima de zero (e, portanto, a taxa de erro era de 50%, naturalmente). Padronizar os dados (subtraindo a média) ajudou, embora o svm resultante ainda não tenha executado perfeitamente ... desconcertante. Parece que o LIBSVM gira apenas o hiperplano em torno do eixo sem traduzi-lo. Talvez você deva tentar subtrair a média dos seus dados, mas parece estranho que o LIBSVM se comporte dessa maneira. Talvez estejamos perdendo alguma coisa.

Pelo que vale a pena, a função MATLAB integrada svmtrainproduziu um classificador com 100% de precisão, sem padronização.

Dave
fonte