Pracuję nad problemem analizy nastrojów, dane wyglądają następująco:
label instances
5 1190
4 838
3 239
1 204
2 127
Więc moje dane są niezrównoważone, ponieważ 1190 instances
są oznaczone 5
. Do klasyfikacji używam SVC firmy scikit . Problem polega na tym, że nie wiem, jak zrównoważyć moje dane we właściwy sposób, aby dokładnie obliczyć precyzję, pamięć, dokładność i wynik f1 dla przypadku wieloklasowego. Więc spróbowałem następujących podejść:
Pierwszy:
wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
wclf.fit(X, y)
weighted_prediction = wclf.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)
Druga:
auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)
print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
average='weighted')
print 'Recall:', recall_score(y_test, auto_weighted_prediction,
average='weighted')
print 'Precision:', precision_score(y_test, auto_weighted_prediction,
average='weighted')
print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)
Trzeci:
clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)
from sklearn.metrics import precision_score, \
recall_score, confusion_matrix, classification_report, \
accuracy_score, f1_score
print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)
F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
0.930416613529
Jednak otrzymuję takie ostrzeżenia:
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with
multiclass or multilabel data or pos_label=None will result in an
exception. Please set an explicit value for `average`, one of (None,
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for
instance, scoring="f1_weighted" instead of scoring="f1"
Jak mogę poprawnie radzić sobie z moimi niezrównoważonymi danymi, aby poprawnie obliczyć metryki klasyfikatora?
python
machine-learning
nlp
artificial-intelligence
scikit-learn
nowy_with_python
źródło
źródło
average
parametru w trzecim przypadku?Odpowiedzi:
Myślę, że istnieje wiele nieporozumień dotyczących tego, które ciężary są używane do czego. Nie jestem pewien, czy dokładnie wiem, co Cię trapi, więc zamierzam poruszyć różne tematy, wytrzymajcie;).
Wagi klas
Wagi z
class_weight
parametru służą do trenowania klasyfikatora . Nie są one używane do obliczania jakichkolwiek używanych przez ciebie metryk : przy różnych wagach klas liczby będą się różnić po prostu dlatego, że klasyfikator jest inny.Zasadniczo w każdym klasyfikatorze typu scikit, wagi klas są używane do informowania modelu, jak ważna jest klasa. Oznacza to, że w trakcie szkolenia klasyfikator dołoży dodatkowych starań, aby odpowiednio sklasyfikować zajęcia z dużymi wagami.
Sposób, w jaki to robią, zależy od algorytmu. Jeśli chcesz uzyskać szczegółowe informacje o tym, jak to działa w przypadku SVC, a dokument nie ma dla Ciebie sensu, możesz o tym wspomnieć.
Metryki
Gdy masz już klasyfikator, chcesz wiedzieć, jak dobrze działa. Tutaj można używać metryki pan wspomniał:
accuracy
,recall_score
,f1_score
...Zwykle, gdy rozkład klas jest niezrównoważony, dokładność jest uważana za zły wybór, ponieważ daje wysokie wyniki modelom, które tylko przewidują najczęstszą klasę.
Nie będę szczegółowo opisywać wszystkich tych wskaźników, ale zauważę, że z wyjątkiem
accuracy
, są one naturalnie stosowane na poziomie klasy: jak widać wprint
raporcie klasyfikacyjnym, są one zdefiniowane dla każdej klasy. Opierają się na pojęciach takich jaktrue positives
lub,false negative
które wymagają określenia, która klasa jest pozytywna .Ostrzeżenie
Otrzymujesz to ostrzeżenie, ponieważ używasz wyniku f1, odwołania i precyzji bez definiowania sposobu ich obliczania! Pytanie mogłoby zostać sformułowane na nowo: jak z powyższego raportu klasyfikacyjnego wyprowadzić jedną liczbę globalną dla wyniku f1? Mógłbyś:
avg / total
wynik powyżej. Nazywa się to również uśrednianiem makro .'weighted'
w scikit-learn waży wynik f1 dzięki wsparciu klasy: im więcej elementów ma klasa, tym ważniejszy jest wynik f1 dla tej klasy w obliczeniach.Oto 3 opcje w scikit-learn, ostrzeżenie mówi, że musisz wybrać jedną . Musisz więc określić
average
argument dla metody punktacji.To, który wybierzesz, zależy od tego, jak chcesz mierzyć wydajność klasyfikatora: na przykład uśrednianie makro nie bierze pod uwagę nierównowagi klas, a wynik f1 klasy 1 będzie tak samo ważny jak wynik f1 klasy 5. Jeśli używasz średniej ważonej, będziesz mieć większe znaczenie dla klasy 5.
Cała specyfikacja argumentów w tych metrykach nie jest teraz super-przejrzysta w scikit-learn, zgodnie z dokumentacją poprawi się w wersji 0.18. Usuwają niektóre nieoczywiste standardowe zachowania i wydają ostrzeżenia, aby programiści to zauważyli.
Obliczanie wyników
Ostatnią rzeczą, o której chciałbym wspomnieć (możesz to pominąć, jeśli jesteś tego świadomy), jest to, że wyniki mają znaczenie tylko wtedy, gdy są obliczane na danych, które klasyfikator nigdy nie widział . Jest to niezwykle ważne, ponieważ każdy wynik uzyskany na podstawie danych użytych do dopasowania klasyfikatora jest całkowicie nieistotny.
Oto sposób na zrobienie tego za pomocą
StratifiedShuffleSplit
, który daje losowe podziały danych (po tasowaniu), które chronią dystrybucję etykiet.Mam nadzieję że to pomoże.
źródło
class_weight={1:10}
oznacza dla danych, które mają 3 klasy?ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.
. Działa dobrze z podziałem testu pociągu, ale czy ktoś może mi pomóc, dlaczego otrzymuję ten błąd z SSS? Dzięki.Wiele bardzo szczegółowych odpowiedzi tutaj, ale myślę, że nie odpowiadasz na właściwe pytania. Jak rozumiem pytanie, istnieją dwie obawy:
1.
Możesz używać większości funkcji oceniających w scikit-learn zarówno z problemami wieloklasowymi, jak i problemami z pojedynczą klasą. Dawny.:
W ten sposób otrzymasz namacalne i możliwe do zinterpretowania liczby dla każdej z klas.
Następnie...
2.
... możesz stwierdzić, czy niezrównoważone dane są problemem. Jeśli punktacja dla mniej reprezentowanych klas (klasa 1 i 2) jest niższa niż dla klas z większą liczbą próbek szkoleniowych (klasa 4 i 5), to wiesz, że niezrównoważone dane są w rzeczywistości problemem i możesz odpowiednio postępować, ponieważ opisane w niektórych innych odpowiedziach w tym wątku. Jednakże, jeśli ten sam rozkład klas jest obecny w danych, które chcesz przewidzieć, Twoje niezrównoważone dane szkoleniowe są dobrym reprezentantem danych, a zatem asymetria jest dobrą rzeczą.
źródło
precision_recall_fscore_support
? Czy etykiety są drukowane na zamówienie?average=None
i zdefiniuj etykiety, a następnie uzyskasz dane, których szukasz, dla każdej z określonych etykiet.Postawione pytanie
Odpowiadając na pytanie „jaki miernik należy zastosować do klasyfikacji wieloklasowej z niezrównoważonymi danymi”: Makro-miara F1. Można również użyć makroprecyzji i przywoływania makr, ale nie są one tak łatwe do interpretacji, jak w przypadku klasyfikacji binarnej, są już włączone do miary F, a nadmiar metryk komplikuje porównanie metod, dostrajanie parametrów i tak dalej.
Uśrednianie w skali mikro jest wrażliwe na nierównowagę klas: jeśli na przykład Twoja metoda działa dobrze w przypadku najpopularniejszych etykiet i całkowicie przeszkadza innym, metryki uśrednione w skali mikro dają dobre wyniki.
Uśrednianie ważenia nie jest odpowiednie dla niezrównoważonych danych, ponieważ jest ważone według liczby etykiet. Ponadto jest on zbyt trudny do zinterpretowania i niepopularny: na przykład nie ma wzmianki o takim uśrednieniu w poniższej bardzo szczegółowej ankiecie, którą gorąco polecam:
Pytanie dotyczące aplikacji
Jednak wracając do twojego zadania, zbadałbym 2 tematy:
Powszechnie używane metryki. Jak mogę wywnioskować po przejrzeniu literatury, istnieją 2 główne wskaźniki oceny:
( link ) - zauważ, że autorzy pracują z prawie takim samym rozkładem ocen, patrz Rysunek 5.
( link )
( link ) - badają zarówno dokładność, jak i MSE, uważając to drugie za lepsze
( link ) - wykorzystują scikit-learning do oceny i podejścia bazowego i stwierdzają, że ich kod jest dostępny; jednak nie mogę jej znaleźć, więc jeśli potrzebujesz, napisz list do autorów, praca jest całkiem nowa i wydaje się być napisana w Pythonie.
Koszt różnych błędów . Jeśli bardziej zależy Ci na unikaniu poważnych błędów, np. Ocenianie oceny od 1 do 5 gwiazdek lub coś w tym rodzaju, spójrz na MSE; jeśli różnica ma znaczenie, ale nie tak bardzo, spróbuj MAE, ponieważ nie ma różnicy kwadratowej; w przeciwnym razie pozostań przy dokładności.
O podejściach, a nie metrykach
Wypróbuj metody regresji, np. SVR , ponieważ generalnie przewyższają one klasyfikatory wieloklasowe, takie jak SVC lub OVA SVM.
źródło
Przede wszystkim jest trochę trudniej, używając samej analizy liczenia, aby stwierdzić, czy dane są niezrównoważone, czy nie. Na przykład: 1 na 1000 pozytywnych obserwacji to tylko szum, błąd lub przełom w nauce? Nigdy nie wiesz.
Dlatego zawsze lepiej jest wykorzystać całą dostępną wiedzę i mądrze wybrać jej status.
Dobra, a co jeśli jest naprawdę niezrównoważony?
Jeszcze raz - spójrz na swoje dane. Czasami można znaleźć jedną lub dwie obserwacje pomnożone sto razy. Czasami warto stworzyć fałszywe obserwacje jednoklasowe.
Jeśli wszystkie dane są czyste, następnym krokiem jest użycie wag klas w modelu predykcyjnym.
A co z metrykami wieloklasowymi?
Z mojego doświadczenia wynika, że żadne z Twoich wskaźników nie jest zwykle używane. Są dwa główne powody.
Po pierwsze: zawsze lepiej jest pracować z prawdopodobieństwami niż z solidną prognozą (bo jak inaczej można oddzielić modele z predykcją 0,9 i 0,6, jeśli oba dają tę samą klasę?).
Po drugie: znacznie łatwiej jest porównać modele predykcyjne i zbudować nowe zależne tylko od jednej dobrej metryki.
Z mojego doświadczenia mogę polecić logloss lub MSE (lub po prostu średni kwadratowy błąd).
Jak naprawić ostrzeżenia sklearn?
Po prostu (jak zauważył yangjie) nadpisz
average
parametr jedną z następujących wartości:'micro'
(oblicz metryki globalnie),'macro'
(oblicz metryki dla każdej etykiety) lub'weighted'
(tak samo jak makro, ale z automatycznymi wagami).Wszystkie ostrzeżenia pojawiły się po wywołaniu funkcji metryk z
average
wartością domyślną,'binary'
która jest nieodpowiednia do przewidywania wieloklasowego.Powodzenia i dobrej zabawy z uczeniem maszynowym!
Edycja:
znalazłem inną rekomendację odpowiadającą, aby przejść na metody regresji (np. SVR), z którymi nie mogę się zgodzić. O ile dobrze pamiętam, nie ma nawet czegoś takiego jak regresja wieloklasowa. Tak, istnieje regresja wielopoziomowa, która jest znacznie inna i tak, w niektórych przypadkach można przełączać się między regresją a klasyfikacją (jeśli klasy w jakiś sposób posortowane), ale jest to dość rzadkie.
To, co poleciłbym (w zakresie scikit-learn), to wypróbowanie innych bardzo potężnych narzędzi klasyfikacyjnych: wzmocnienie gradientu , losowy las (mój ulubiony), KNeighbors i wiele innych.
Następnie możesz obliczyć średnią arytmetyczną lub geometryczną między przewidywaniami i przez większość czasu uzyskasz jeszcze lepszy wynik.
źródło