Próbuję nauczyć mojego algorytmu SVM przy użyciu danych kliknięć i konwersji przez osoby, które widzą banery. Główny problem polega na tym, że kliknięcia stanowią około 0,2% wszystkich danych, więc jest to duża dysproporcja. Kiedy używam prostej maszyny SVM w fazie testowania, zawsze przewiduję tylko klasę "widok", a nigdy "kliknięcie" lub "konwersję". Średnio daje to 99,8% poprawnych odpowiedzi (z powodu dysproporcji), ale daje 0% prawych prognoz, jeśli zaznaczysz "kliknięcie" lub "konwersję". W jaki sposób można dostroić algorytm SVM (lub wybrać inny), aby uwzględnić dysproporcję?Jak powinienem uczyć algorytmu uczenia maszynowego przy użyciu danych o dużej dysproporcji klas? (SVM)
Odpowiedz
Najbardziej podstawowym podejściem jest użycie tak zwanego "schematu ważenia klasy" - w klasycznym formularzu SVM istnieje parametr C
używany do kontrolowania liczby błędów klasyfikacji. Można go zmienić na parametry C1
i C2
dla klas odpowiednio 1 i 2. Najczęstszym wyborem C1
i C2
dla danego C
jest umieszczenie
C1 = C/n1
C2 = C/n2
gdzie n1
i n2
są rozmiary klasy 1 i 2 odpowiednio. Więc "karzesz" SVM za pomijanie klasy mniejszej, o wiele trudniejszej, niż za typową dla missclassification.
Wiele istniejących bibliotek (takich jak libSVM) obsługuje ten mechanizm z parametrami klasy class_weight.
Przykład użyciu Python i sklearn
print __doc__
import numpy as np
import pylab as pl
from sklearn import svm
# we create 40 separable points
rng = np.random.RandomState(0)
n_samples_1 = 1000
n_samples_2 = 100
X = np.r_[1.5 * rng.randn(n_samples_1, 2),
0.5 * rng.randn(n_samples_2, 2) + [2, 2]]
y = [0] * (n_samples_1) + [1] * (n_samples_2)
# fit the model and get the separating hyperplane
clf = svm.SVC(kernel='linear', C=1.0)
clf.fit(X, y)
w = clf.coef_[0]
a = -w[0]/w[1]
xx = np.linspace(-5, 5)
yy = a * xx - clf.intercept_[0]/w[1]
# get the separating hyperplane using weighted classes
wclf = svm.SVC(kernel='linear', class_weight={1: 10})
wclf.fit(X, y)
ww = wclf.coef_[0]
wa = -ww[0]/ww[1]
wyy = wa * xx - wclf.intercept_[0]/ww[1]
# plot separating hyperplanes and samples
h0 = pl.plot(xx, yy, 'k-', label='no weights')
h1 = pl.plot(xx, wyy, 'k--', label='with weights')
pl.scatter(X[:, 0], X[:, 1], c=y, cmap=pl.cm.Paired)
pl.legend()
pl.axis('tight')
pl.show()
W szczególności, w sklearn można po prostu włączyć automatycznego ważenia poprzez ustawienie class_weight='auto'
.
Opisano szereg technik. Jeden prosty (ale bardzo zła metoda SVM) jest po prostu replikacji klasę (-y) mniejszościowy aż masz balans:
http://www.ele.uri.edu/faculty/he/PDFfiles/ImbalancedLearning.pdf
Tylko dla kompletności - replikacja klasy mniejszości powinna ** nigdy ** być używana w SVM. Jest to równoważne użyciu ciężarów klasowych, podczas gdy w tym samym czasie jest całkowicie nieefektywne pod względem czasu szkolenia (i testowania). – lejlot
Edytowałem moją oryginalną odpowiedź, aby odzwierciedlić komentarz Lejlot. – denson
wyczynia-próbkowanie Opcjonalnie klasa mniejszościowych? –
Czy możesz powiedzieć więcej o tym, co masz na myśli mówiąc o pobieraniu próbek? – rvnikita
możliwy duplikat [regresji logistycznej sklearn z klasami niezrównoważonymi] (http://stackoverflow.com/questions/14863125/sklearn-logistic-regression-with-balanced-classes) –