Popraw klasyfikację za pomocą wielu zmiennych kategorycznych

37

Pracuję nad zbiorem danych z ponad 200 000 próbek i około 50 cechami na próbkę: 10 zmiennych ciągłych, a pozostałe ~ 40 to zmienne jakościowe (kraje, języki, dziedziny nauki itp.). Dla tych zmiennych kategorialnych masz na przykład 150 różnych krajów, 50 języków, 50 dziedzin naukowych itp.

Jak dotąd moje podejście jest następujące:

  1. Dla każdej zmiennej kategorialnej o wielu możliwych wartościach, weź tylko tę, która ma więcej niż 10000 próbek, która przyjmuje tę wartość. Zmniejsza to do 5-10 kategorii zamiast 150.

  2. Zbuduj zmienną fikcyjną dla każdej kategorii (jeśli 10 krajów, to dla każdej próbki dodaj wektor binarny o rozmiarze 10).

  3. Wprowadź losowy klasyfikator leśny (sprawdź parametry itp.) Tymi danymi.

Obecnie przy takim podejściu udaje mi się uzyskać jedynie 65% dokładności i wydaje mi się, że można zrobić więcej. Szczególnie nie jestem zadowolony z mojej 1), ponieważ uważam, że nie powinienem arbitralnie usuwać „najmniej istotnych wartości” zgodnie z liczbą próbek, jakie mają, ponieważ te mniej reprezentowane wartości mogą być bardziej dyskryminujące. Z drugiej strony, moja pamięć RAM nie może sobie pozwolić na dodanie 500 danych * 200000 wierszy do danych, zachowując wszystkie możliwe wartości.

Czy masz jakieś sugestie, aby poradzić sobie z tymi bardzo kategorycznymi zmiennymi?

Bertrand R.
źródło
2
Jeśli nadal jesteś zainteresowany, możesz sprawdzić moją odpowiedź na temat zmniejszenia wymiarów i moją odpowiedź na temat hierarchicznej klasyfikacji .
Aleksandr Blekh
1
Kiedy mówisz „buduj zmienną fikcyjną dla każdego kategorycznego” , brzmi to tak, jakbyś używał Pythona, a nie R? R randomforest może natywnie obsługiwać kategorie, także wynikające z tego zmniejszenie pamięci. Spróbuj R.
smci
Zobacz także stats.stackexchange.com/questions/146907/…
kjetil b halvorsen

Odpowiedzi:

20

1) Losowe lasy powinny być w stanie obsłużyć wartości jakościowe w sposób natywny, więc poszukaj innej implementacji, abyś nie musiał kodować wszystkich tych funkcji i zajmował całą pamięć.

2) Problem z kategorycznymi cechami wysokiej kardynalności polega na tym, że łatwo jest z nimi zmieścić się. Możesz mieć wystarczającą ilość danych, aby nie stanowiło to problemu, ale uważaj na to.

3) Sugeruję przyjrzenie się losowemu wyborowi cech opartych na lesie przy użyciu metody zaproponowanej przez Briemana lub sztucznych kontrastów . Metoda sztucznych kontrastów (ACE) jest interesująca, ponieważ porównuje ważność tej funkcji ze znaczeniem potasowanej wersji samej siebie, która walczy z niektórymi problemami wysokiej kardynalności. Pojawiła się nowa praca „Lasy losowe z przewodnikiem po modułach”, która może być interesująca, jeśli masz o wiele więcej funkcji, ponieważ wykorzystuje ona metodę wyboru cech, która jest świadoma grup cech ściśle skorelowanych.

4) Inną czasami używaną opcją jest ulepszenie algorytmu, aby używał skrzynek z torby w celu dokonania ostatecznego wyboru funkcji po dopasowaniu podziałów w skrzynkach z torby, co czasem pomaga w walce z przeregulowaniem.

Jest prawie pełna realizacja ace tutaj i mam effichent więcej pamięci / szybkie wdrożenie rf, który obsługuje zmienne kategoryczne natywnie tutaj ... The -evaloob podpory opcja opcja 4 pracuję na dodanie wsparcia dla ACE i kilka innych rf oparte na metodach wyboru funkcji, ale jeszcze tego nie zrobiono.

Ryan Bressler
źródło
4
Wszystkie te sugestie są interesujące, zgadzam się, że losowy las powinien obsługiwać natywnie zmienne kategorialne, ale scikit-learn nie ... Myślę, że to jedna z głównych wad programu Scikit. Spróbuję kodu na moich danych, aby zobaczyć, co się stanie, i zobaczę inne sugestie!
Bertrand R
1
Wypróbuj implementację R. Uruchamianie go to jedna wkładka. Odczytywanie danych jest niezwykle łatwe, a nowa implementacja równoległych urządzeń jest niesamowicie szybka i wydajna pod względem pamięci: r-bloggers.com/... Z drugiej strony. Czy twoje klasy są niezrównoważone? w implementacji r możesz wyhodować każde drzewo ze zrównoważonej próbki bootstrap sampsize = c (x, x). To dało mi lepsze klasyfikacje binarne. Możesz bawić się rozmiarami i bardzo łatwo modyfikować klasyfikację, korzystając z wyjść R macierzy pomieszania OOB.
JEquihua
2
Losowa implementacja R R pozwala na czynniki o maksymalnie 32 poziomach. scikit-learn jest mniej restrykcyjny, pod warunkiem, że najpierw tworzysz zmienne fikcyjne (patrz pandas.get_dummiesfunkcja). Implementacja losowego lasu przez H2O była dla mnie bardzo dobra (patrz 0xdata.com/docs/master/model/rf ).
Alex Woolford,
1
jest nowsza i szybsza implementacja losowego lasu, pakiet nazywa się ranger. Naprawdę świetne rzeczy. O rząd wielkości szybciej i nie ma limitu 32 poziomów.
marbel
6

Dlaczego zamiast zmumifikować swoje kategorie, po prostu nie użyłbyś jednej zmiennej numerycznej dla każdej z nich? W kontekście losowych lasów często zastanawiałem się nad konsekwencjami takiego postępowania (ponieważ zgadzam się, że wprowadzanie porządku w kategorycznych danych, z którym często nie ma sensu, wydaje się podejrzane), ale w praktyce (przynajmniej z wdrożoną przez scikit metodą uczenia RF, której używam), często zauważyłem, że nie ma to wpływu na wyniki (choć nie jestem pewien, dlaczego).

Cjauvin
źródło
1
Jest to dobre w przypadku cech jakościowych o wartości n <= 3, ponieważ można wygenerować wszystkie te same podziały, tak jak w przypadku funkcji domyślnie uznanych za kategoryczne. Dla większych n możliwe jest uzyskanie zestawów podziałów, które są równoważne podziałowi kategorycznemu, ale algorytm może lub nie może znaleźć ich tak skutecznie ... jednak jeśli podzielisz tę cechę na n liczbowych, zmniejszysz również efektywność, z jaką algorytm może znaleźć podziały. Ktoś musi dodać obsługę zmiennych jakościowych do implementacji scikit-learn, ponieważ w przeciwnym razie jest to świetne.
Ryan Bressler,
Zgadzam się z tobą, gdy mówisz, że wprowadzanie porządkowania danych kategorycznych wydaje się podejrzane ... Wolałbym tego nie robić, ale mogę przynajmniej spróbować i zobaczyć, co się stanie!
Bertrand R
4
Miałem długą dyskusję na temat tego pytania na liście mailingowej sklearn (możesz przeczytać jego części tutaj: mail-archive.com/[email protected]/… ). Jeden z implementatorów był zdania, że ​​przy wystarczająco głębokich drzewach cechy kategorialne zakodowane porządkowo mogą działać całkiem dobrze (oprócz tego, że są bardziej wydajne obliczeniowo). W każdym razie, jeśli spróbujesz, bardzo chciałbym usłyszeć o twoich wynikach / wnioskach, ponieważ to jest problem, na który ciągle wpadam.
cjauvin
1
Próbowałem więc zachować jedną zmienną numeryczną dla zmiennych kategorycznych, i faktycznie działa ona zaskakująco dobrze i znacznie lepiej niż dodawanie dużej liczby pozycji binarnych ... Próbowałem również sortować wartości według ich średniej wrt do celu . I to też działa dobrze
Bertrand R
Wcale mnie to nie dziwi ... jest to zgodne z tym, co zaobserwowałem w kilku różnych ustawieniach, choć sądząc po liczbie głosów pozytywnych, jest to raczej sprzeczny z intuicją pomysł.
cjauvin
5

Myślę, że powinieneś rozważyć / więcej technik redukcji zmiennej . Pozbywa się nie tak wpływowych predyktorów.

Dużo czytałem o przetwarzaniu danych i jest to świetne rozwiązanie, aby zmniejszyć liczbę twoich zmiennych.

Moje sugestie są następujące:

  • w przypadku zmiennych jakościowych zastąp brakujące wartości kategorią „brak”. Może wprowadzić błąd systematyczny, jeśli danych nie brakuje przypadkowo, ale przynajmniej wszystkie obserwacje pozostaną nienaruszone, a brak może ujawnić inne zachowanie.
  • wyeliminuj predyktory wariancji zerowej lub predyktory wariancji bliskiej zeru (uważaj, aby nie wyeliminować fikcyjnych zmiennych o wysokich niezrównoważonych kategoriach, które mogą skutecznie oddzielić twoje Y. Zrób kilka wykresów dla zmiennych, które Twoim zdaniem mogą być ważne). W R możesz użyć 'nzv'funkcji z 'caret'pakietu. To znacznie zmniejszy twój wymiar danych.
  • wyeliminować skorelowane predyktory . Użyj macierzy korelacji Kendalla, ponieważ lepiej jest konstruować w obecności zmiennych kategorialnych. Minusem jest to, że musisz przekształcić wszystkie swoje nominalne zmienne w kategoryczne.
  • istnieją metody wyboru funkcji, które jeszcze bardziej zmniejszą ich liczbę (grupowanie - wybierasz pojedynczego przedstawiciela każdego klastra, regresję LASSO itp.). Nie miałem jeszcze okazji ich przetestować, ponieważ pozostałe kroki zmniejszyły moje zmienne do poniżej 100.

Sugerowałbym również użycie algorytmu AdaBoost zamiast RF. Osobiście przeprowadzone przeze mnie badania dały mi bardzo podobne współczynniki Giniego dla obu tych metod. Zaletą AdaBoost jest to, że w R obsługuje brakujące obserwacje. Możesz więc pominąć pierwszy krok na tej liście

Mam nadzieję, że trochę pomogło. Powodzenia

lorelai
źródło
4

Możesz rozważyć modele z efektami mieszanymi. Są one popularne w naukach społecznych ze względu na ich wyniki w kategoriach danych o wysokiej kardynalności, a ja wykorzystałem je do stworzenia świetnych modeli predykcyjnych, które przewyższają popularne podejścia do uczenia maszynowego, takich jak drzewa ze wzmocnieniem gradientu, losowe lasy i regresja logistyczna z elastyczną siatką. Najbardziej znaną implementacją jest pakiet Rme lme4; funkcją, której użyjesz do klasyfikacji, jest glmer, który implementuje regresję logistyczną z mieszanymi efektami. Być może masz problemy ze skalowaniem zestawu danych, ale wykonałem 80 000 wierszy z 15 funkcjami bez większych trudności.

Paweł
źródło
2
  1. Kiedy mówisz „buduj zmienną fikcyjną dla każdego kategorycznego” , brzmi to tak, jakbyś używał Pythona, a nie R? R randomforest może natywnie obsługiwać kategorie, także wynikające z tego zmniejszenie pamięci. Wypróbuj R.

  2. Następnie nie trzeba ręcznie przycinać / łączyć poziomów jakościowych, co brzmi jak poważny ból. I nawet jeśli tak, nie masz gwarancji, że najbardziej zaludnione kategorie są najbardziej przewidywalne. Kontroluj złożoność lasów losowych za pomocą parametru nodesize : zacznij od dużego nodesize i stopniowo go zmniejszaj (jest to wyszukiwanie hiperparametrów).

  3. Przydatny będzie wybór zmiennych. @lorelai daje dobre rekomendacje. Spróbuj wyeliminować bezużyteczne (mało ważne lub wysoce skorelowane) funkcje. Konstrukcja drzewa jest kwadratowa w stosunku do liczby funkcji, więc jeśli nawet wyeliminujesz jedną trzecią, zapłaci dywidendy.

smci
źródło
0

Powinieneś spojrzeć na pakiet H2O.ai. Obsługuje zmienne kategoryczne od razu po wyjęciu z pudełka, bez konieczności kodowania (upewnij się, że zmienne są czynnikami).

Szczególnie podoba mi się ich implementacja Gradient Boosted Machine (GBM), ponieważ po zbudowaniu modelu można następnie spojrzeć na zmienne znaczenie. GBM mają również tę zaletę, że są odporne na nadmierne dopasowanie.

Jeśli chcesz eksplorować inne modele, mają one: GLM, Random Forest, Naive Bayes, Deep Learning itp.

Zobacz: http://docs.h2o.ai/h2o/latest-stable/h2o-docs/data-science/gbm.html

Jest także łatwy w instalacji (Windows, Linux, Mac) i łatwy w obsłudze z API za pomocą R, Python, Java i Scala.

Może używać wielu rdzeni, aby przyspieszyć.

W najbliższej przyszłości będą obsługiwać procesory graficzne.

Jest to również oprogramowanie typu open source i bezpłatne (istnieje obsługa Enterprise).

Clem Wang
źródło