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.weightsparametru e1071interfejsu pakietu R, libsvmaby 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.weightszestawem 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.weightsParamter działa, sortowania , jako niższą masę I a, tym niższe jest reprezentowana w tej symulacji (a jeśli pominąć class.weightszwraca 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.weightsparametru?
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)