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)
źródło
Odpowiedzi:
Myślę, że może to zależeć od wartości C i liczby posiadanych wzorów. SVM próbuje znaleźć dyskryminator maksymalnego marginesu, więc jeśli masz rzadkie dane, możliwe jest, że SVM może znaleźć rozwiązanie z twardym marginesem bez żadnego mnożnika Lagrange'a osiągającego górne granice (w takim przypadku stosunek kar dla każdego z nich klasa jest w zasadzie nieistotna, ponieważ luźne wartości są małe lub zerowe. Spróbuj zwiększyć liczbę wzorców treningowych i sprawdź, czy to ma wpływ (ponieważ zmniejsza to prawdopodobieństwo znalezienia rozwiązania z marginesem twardym w ramach ograniczeń pola) .
Co ważniejsze, optymalne wartości C są zależne od danych, nie można po prostu ustawić ich na niektóre z góry określone wartości, ale zamiast tego zoptymalizować je, minimalizując błąd pomijany lub ograniczenia związane z generalizacją. Jeśli masz niezrównoważone klasy, możesz ustalić stosunek wartości dla każdej klasy i zoptymalizować średnią karę za wszystkie wzorce.
źródło
caret
pakietu lub wbudowanejtune()
funkcji do strojenia parametrów modelu, więc szczególnie podoba mi się twój drugi pomysł, jak sobie z tym poradzić w praktyce, dostosowując schemat ponownego próbkowania, aby faworyzować klasę mniejszości. Bardzo mile widziane.w szkoleniu svm znajdujemy wektory pomocnicze, aby stworzyć dyskryminującą granicę, a gdy jest wystarczająca ilość wektorów pomocniczych dla danych wszystkich klas, nie byłoby problemu. w dokładności wyników zestawu testowego należy pamiętać o równej ilości danych dla wszystkich klas w prawdziwym świecie, a dla uzyskania rzeczywistych wyników należy manipulować danymi, a także odpowiednio uwzględnić je w rzeczywistej sytuacji.
źródło