J'essaie de construire un SVM à partir de données de formation où un groupe est représenté plus que l'autre. Cependant, les groupes seront également représentés dans les éventuelles données de test. Par conséquent, je voudrais utiliser le class.weights
paramètre de l' e1071
interface du package R libsvm
pour équilibrer l'influence des deux groupes dans les données d'entraînement.
Comme je ne savais pas exactement comment ces poids devaient être spécifiés, j'ai mis en place un petit test:
- Générez des données nulles (caractéristiques aléatoires; rapport 2: 1 entre les étiquettes de groupe)
- Ajustez un svm avec le
class.weights
jeu de paramètres. - Prédisez un tas de nouveaux ensembles de données nuls et examinez les proportions de classe.
- Répliquez l'ensemble du processus plusieurs fois pour différents ensembles d'entraînement nuls.
Voici le code R que j'utilise:
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 tout cela, je m'attendais à une sortie ~ 0,5, cependant, ce n'est pas ce que j'ai obtenu:
> mean(replicate(50, nullSVM(50, 300)))
[1] 0.6429987
Le class.weights
paramètre fonctionne, en quelque sorte , plus le poids I est faible a
, plus il est représenté dans cette simulation (et si je l'omet, class.weights
il revient proche de 1) ... mais je ne comprends pas pourquoi simplement utiliser des poids de 1: 2 ( pour les données d'entraînement qui sont de 2: 1) ne me fait pas descendre à 50%.
Si je ne comprends pas bien les SVM, quelqu'un peut-il expliquer ce point? (ou envoyer des références?)
Si je me trompe, quelqu'un peut-il me dire comment utiliser correctement le class.weights
paramètre?
Serait-ce peut-être un bug? (Je ne pense pas, car je comprends que ce logiciel et le libsvm sous-jacent sont assez matures)