Mam wiele problemów ze zrozumieniem, jak działa class_weight
parametr regresji logistycznej scikit-learn.
Sytuacja
Chcę użyć regresji logistycznej, aby przeprowadzić klasyfikację binarną na bardzo niezrównoważonym zestawie danych. Klasy są oznaczone jako 0 (negatywne) i 1 (pozytywne), a obserwowane dane są w stosunku około 19: 1, przy czym większość próbek daje wynik negatywny.
Pierwsza próba: ręczne przygotowanie danych treningowych
Dane, które miałem, podzieliłem na rozłączne zbiory do treningu i testów (około 80/20). Następnie ręcznie pobierałem losowe próbki danych szkoleniowych, aby uzyskać dane szkoleniowe w proporcjach innych niż 19: 1; od 2: 1 do 16: 1.
Następnie wytrenowałem regresję logistyczną na tych różnych podzbiorach danych szkoleniowych i wykreśliłem pamięć (= TP / (TP + FN)) jako funkcję różnych proporcji treningowych. Oczywiście przywołanie obliczono na rozłącznych próbkach TEST, które miały obserwowane proporcje 19: 1. Uwaga, chociaż trenowałem różne modele na różnych danych uczących, obliczyłem przypomnienia dla nich wszystkich na tych samych (rozłącznych) danych testowych.
Wyniki były zgodne z oczekiwaniami: przywołanie było około 60% przy proporcjach treningu 2: 1 i spadło dość szybko, gdy osiągnęło 16: 1. Było kilka proporcji 2: 1 -> 6: 1, gdzie zapamiętanie było przyzwoicie powyżej 5%.
Druga próba: wyszukiwanie sieci
Następnie chciałem przetestować różne parametry regularyzacji, więc użyłem GridSearchCV i utworzyłem siatkę kilku wartości C
parametru oraz class_weight
parametru. Aby przetłumaczyć moje n: m proporcje negatywnych: pozytywnych próbek szkoleniowych na język słownikowy class_weight
, pomyślałem, że po prostu określę kilka słowników w następujący sposób:
{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 } #expected 4:1
a także włączyłem None
i auto
.
Tym razem wyniki były totalnie oszukane. Wszystkie moje przypomnienia wyszły niewielkie (<0,05) dla każdej wartości class_weight
oprócz auto
. Mogę więc tylko założyć, że moje rozumienie, jak ustawić class_weight
słownik, jest błędne. Co ciekawe, class_weight
wartość „auto” w wyszukiwaniu w siatce wynosiła około 59% dla wszystkich wartości C
, a zgadłem, że wynosi 1: 1?
Moje pytania
Jak prawidłowo wykorzystujesz
class_weight
dane treningowe, aby osiągnąć inną równowagę w porównaniu z tym, co faktycznie je dajesz? Konkretnie, do jakiego słownika należy przejść, abyclass_weight
zastosować n: m proporcje negatywnych: pozytywnych próbek szkoleniowych?Jeśli przekażesz różne
class_weight
słowniki do GridSearchCV, czy podczas walidacji krzyżowej zrównoważy on dane krotności treningowej zgodnie ze słownikiem, ale użyje prawdziwych podanych proporcji próbki do obliczenia mojej funkcji oceniania na krotnie testowym? Ma to kluczowe znaczenie, ponieważ każdy wskaźnik jest dla mnie przydatny tylko wtedy, gdy pochodzi z danych w obserwowanych proporcjach.Jaka jest
auto
wartośćclass_weight
, jeśli chodzi o proporcje? Czytam dokumentację i zakładam, że „równoważy dane odwrotnie proporcjonalnie do ich częstotliwości”, czyli po prostu daje wynik 1: 1. Czy to jest poprawne? Jeśli nie, czy ktoś może wyjaśnić?
źródło
Odpowiedzi:
Po pierwsze, samo przywołanie może nie być dobre. Możesz po prostu osiągnąć 100% wycofania, klasyfikując wszystko jako pozytywną klasę. Zwykle sugeruję użycie AUC do wyboru parametrów, a następnie znalezienia progu dla punktu pracy (powiedzmy danego poziomu dokładności), który Cię interesuje.
Jak to
class_weight
działa: penalizuje błędy w próbkachclass[i]
zclass_weight[i]
zamiast 1. Tak więc wyższa waga klasy oznacza, że chcesz położyć większy nacisk na klasę. Z tego, co mówisz, wydaje się, że klasa 0 występuje 19 razy częściej niż klasa 1. Dlatego należy zwiększyć wartośćclass_weight
klasy 1 względem klasy 0, powiedzmy {0: .1, 1: .9}. Jeśliclass_weight
suma nie wynosi 1, zasadniczo zmieni parametr regularyzacji.Aby dowiedzieć się
class_weight="auto"
, jak to działa, możesz rzucić okiem na tę dyskusję . W wersji deweloperskiej możesz użyćclass_weight="balanced"
, co jest łatwiejsze do zrozumienia: w zasadzie oznacza to replikowanie mniejszej klasy, aż będziesz mieć tyle próbek, co w większej, ale w niejawny sposób.źródło
Pierwsza odpowiedź jest dobra, aby zrozumieć, jak to działa. Ale chciałem zrozumieć, jak powinienem go używać w praktyce.
PODSUMOWANIE
class_weight="balanced"
działa przyzwoicie pod nieobecność ciebie, który chcesz optymalizować ręcznieclass_weight="balanced"
czemu wychwytujesz więcej prawdziwych zdarzeń (wyższa dokładność PRAWDA), ale także masz większe prawdopodobieństwo otrzymania fałszywych alertów (niższa dokładność PRAWDA)NB
Wynik może się różnić w przypadku korzystania z RF lub GBM. sklearn nie ma
class_weight="balanced"
dla GBM, ale lightgbm maLGBMClassifier(is_unbalance=False)
KOD
źródło