SVM com tamanhos de grupo desiguais nos dados de treinamento

12

Estou tentando criar um SVM a partir de dados de treinamento em que um grupo é representado mais que o outro. No entanto, os grupos serão igualmente representados nos eventuais dados do teste. Portanto, eu gostaria de usar o class.weightsparâmetro da e1071interface do pacote R libsvmpara equilibrar a influência dos dois grupos nos dados de treinamento.

Como não sabia exatamente como esses pesos deveriam ser especificados, configurei um pequeno teste:

  1. Gere alguns dados nulos (recursos aleatórios; proporção 2: 1 entre rótulos de grupos)
  2. Ajuste um svm com o class.weightsconjunto de parâmetros.
  3. Preveja vários novos conjuntos de dados nulos e analise as proporções da classe.
  4. Replicar todo o processo várias vezes para diferentes conjuntos de treinamento nulo.

Aqui está o código R que estou usando:

nullSVM <- function(n.var, n.obs) {
    # Simulate null training data
    vars   = matrix(rnorm(n.var*n.obs), nrow=n.obs)
    labels = rep(c('a', 'a', 'b'), length.out=n.obs)
    data   = data.frame(group=labels, vars)

    # Fit SVM
    fit = svm(group ~ ., data=data, class.weights=c(a=0.5, b=1))

    # Calculate the average fraction of 'a' we would predict from null test data
    mean(replicate(50, table(predict(fit, data.frame(matrix(rnorm(n.var*n.obs), nrow=n.obs))))[1])) / n.obs
}

library(e1071)
set.seed(12345)
mean(replicate(50, nullSVM(50, 300)))

De tudo isso, eu estava esperando uma saída ~ 0.5, no entanto, não foi isso que obtive:

> mean(replicate(50, nullSVM(50, 300)))
[1] 0.6429987

O class.weightsparamter está funcionando, espécie de , como o menor peso I a, menor é representado nesta simulação (e se eu omitir class.weightsele retorna próximo de 1) ... mas eu não entendo por que simplesmente usando pesos de 1: 2 ( para dados de treinamento que são 2: 1) não me leva até 50%.

Se estou entendendo mal os SVMs, alguém pode explicar esse ponto? (ou enviar algumas referências?)

Se estou fazendo errado, alguém pode me dizer a maneira correta de usar o class.weightsparâmetro?

Poderia ser um bug? (Acho que não, pois entendo que este software e a libsvm subjacente são bastante maduros)

John Colby
fonte
Não tenho experiência com libsvm, mas com LiblineaR, os pesos das classes são cruciais. Sem a configuração correta, você obtém resultados abaixo do ideal se suas aulas estiverem muito desequilibradas. Eu sugeriria: Obtenha um conjunto de dados real com classes desequilibradas e tente valores diferentes de class.weights (no LiblineaR wi). O LiblineaR é ordens de magnitude mais rápidas para um núcleo linear e também penalizou métodos. Na minha experiência, você primeiro encontrar um peso classe decente e, em seguida, otimizar C.
marbel

Respostas:

7

Eu acho que pode depender dos valores de C e do número de padrões que você possui. O SVM tenta encontrar a margem máxima discriminante; portanto, se você tiver dados esparsos, é possível que o SVM encontre a solução de margem dura sem que nenhum dos multiplicadores Lagrange atinja seus limites superiores (nesse caso, a taxa de penalidades para cada classe é essencialmente irrelevante, pois as folgas são pequenas ou zero.Tente aumentar o número de padrões de treinamento e veja se isso tem algum efeito (pois isso torna menos provável que a solução de margem rígida possa ser encontrada dentro das restrições da caixa) .

Mais importante, os valores ótimos de C são dependentes dos dados; você não pode apenas configurá-los para alguns valores predeterminados, mas, em vez disso, otimizá-los, minimizando o erro de deixar um para fora ou algum limite de generalização. Se você tiver classes desequilibradas, poderá fixar a proporção dos valores para cada classe e otimizar a penalidade média sobre todos os padrões.

Dikran Marsupial
fonte
Isso faz sentido. Quando reduzo o número de recursos e aumente o número de observações nesta simulação, o valor da saída se aproxima de 0,5. No entanto, nunca chega lá - mesmo com 900 linhas e apenas 1 coluna.
John Colby
É claro que em dados reais eu sempre uso o caretpacote ou a tune()função incorporada para o ajuste de parâmetros do modelo, por isso gosto especialmente da sua segunda ideia de como lidar com isso na prática, ajustando o esquema de reamostragem para favorecer a classe minoritária. Muito apreciado.
John Colby
Ainda bem que sua sugestão foi útil. Existe um artigo sobre como definir a proporção ideal que também pode ser útil theoval.cmp.uea.ac.uk/publications/pdf/ijcnn2001.pdf No entanto, a correção teórica ideal nem sempre é ideal na prática, portanto os melhores resultados podem na verdade, é obtido ajustando os dois parâmetros C separados sem forçar uma proporção específica, mas ponderando os padrões de acordo com a classe ao avaliar o critério de seleção de modelo de exclusão única.
Dikran Marsupial
2
Eu também acrescentaria que hoje em dia tenho a tendência de usar a regressão de crista do kernel em vez de SVMs, pois você não tem esse tipo de problemas contra-intuitivos devido à descontinuidade na derivada da função de perda. Com frequência, se você ajustar um SV2 L2 corretamente, você acaba com um valor muito pequeno de C e todos os dados são SVs; nesse momento, você tem um modelo KRR de qualquer maneira. Quanto mais eu os usei, menos útil encontrei SVMs na prática, embora as idéias teóricas que trouxeram tenham sido vitais.
Dikran Marsupial
0

no treinamento, svm encontre vetores de suporte para criar um limite discriminativo e, quando houver vetores de suporte suficientes para todos os dados das classes, isso não será problema. na precisão dos resultados do conjunto de testes, você deve considerar a quantidade de dados de igualdade para todas as classes no mundo real e, para obter resultados reais, você deve manipular os dados e eles são considerados adequadamente na situação real.

ho3ein
fonte
Essa resposta não está clara no momento - considerei fazer uma edição de cópia, mas há vários lugares em que não tinha certeza do que você pretendia. A pontuação e a gramática são importantes para transmitir significado.
Silverfish