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.weights
parâmetro da e1071
interface do pacote R libsvm
para 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:
- Gere alguns dados nulos (recursos aleatórios; proporção 2: 1 entre rótulos de grupos)
- Ajuste um svm com o
class.weights
conjunto de parâmetros. - Preveja vários novos conjuntos de dados nulos e analise as proporções da classe.
- 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.weights
paramter está funcionando, espécie de , como o menor peso I a
, menor é representado nesta simulação (e se eu omitir class.weights
ele 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.weights
parâmetro?
Poderia ser um bug? (Acho que não, pois entendo que este software e a libsvm subjacente são bastante maduros)