Próbuję zbudować maszynę SVM na podstawie danych szkoleniowych, w których jedna grupa jest reprezentowana bardziej niż druga. Grupy będą jednakowo reprezentowane w ostatecznych danych testowych. Dlatego chciałbym użyć class.weights
parametru e1071
interfejsu pakietu R, libsvm
aby zrównoważyć wpływ dwóch grup na dane treningowe.
Ponieważ nie byłem pewien, jak dokładnie określić te wagi, przygotowałem mały test:
- Wygeneruj niektóre dane zerowe (cechy losowe; stosunek 2: 1 między etykietami grupy)
- Dopasuj svm z
class.weights
zestawem parametrów. - Przewiduj kilka nowych zerowych zbiorów danych i spójrz na proporcje klas.
- Powtórz cały proces wiele razy dla różnych zerowych zestawów treningowych.
Oto kod R, którego używam:
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)))
Z tego wszystkiego spodziewałem się wyniku ~ 0,5, ale nie to otrzymałem:
> mean(replicate(50, nullSVM(50, 300)))
[1] 0.6429987
class.weights
Paramter działa, sortowania , jako niższą masę I a
, tym niższe jest reprezentowana w tej symulacji (a jeśli pominąć class.weights
zwraca bliski 1) ... ale nie rozumiem, dlaczego po prostu za pomocą odważników od 1: 2 ( dla danych treningowych, które są 2: 1) nie doprowadza mnie do 50%.
Jeśli nie rozumiem SVM, czy ktoś może wyjaśnić ten punkt? (lub wysłać referencje?)
Jeśli robię to źle, czy ktoś może powiedzieć mi właściwy sposób użycia class.weights
parametru?
Czy to może być błąd? (Myślę, że nie, ponieważ rozumiem, że to oprogramowanie i leżący u jego podstaw libsvm są dość dojrzałe)