Losowy Las R nie może obsłużyć więcej niż 32 poziomy. Co to jest obejście?

22

Losowy pakiet R. pakietu R nie może obsłużyć współczynnika z więcej niż 32 poziomami. Gdy ma więcej niż 32 poziomy, emituje komunikat o błędzie:

Nie obsługuje predyktorów jakościowych z więcej niż 32 kategoriami.

Ale dane, które mam, mają kilka czynników. Niektóre z nich mają ponad 1000 poziomów, a niektóre ponad 100. Ma nawet „stan” stanów zjednoczonych, który wynosi 52.

Oto moje pytanie.

  1. Dlaczego są takie ograniczenia? randomForest odmawia uruchomienia nawet dla prostej sprawy.

    > d <- data.frame(x=factor(1:50), y=1:50)
    > randomForest(y ~ x, data=d)
      Error in randomForest.default(m, y, ...) : 
      Can not handle categorical predictors with more than 32 categories.

    Jeśli jest to spowodowane ograniczeniem pamięci, w jaki sposób scikit learn randomForeestRegressor może działać z więcej niż 32 poziomami?

  2. Jak najlepiej poradzić sobie z tym problemem? Załóżmy, że mam zmienne niezależne X1, X2, ..., X50, a Y jest zmienną zależną. Załóżmy, że X1, X2 i X3 mają ponad 32 poziomy. Co powinienem zrobić?

    Myślę o uruchomieniu algorytmu grupowania dla każdego z X1, X2 i X3, w którym odległość jest zdefiniowana jako różnica w Y. Uruchomię trzy klastry, ponieważ istnieją trzy zmienne problematyczne. I w każdej grupie chciałbym znaleźć podobne poziomy. I połączę je.

    Jak to brzmi?

Minkoo Seo
źródło
Przeszukiwanie sieci za pomocą nazwy pakietu i komunikatu o błędzie zawiera kilka odpowiedzi.
Roland
5
@Roland Właściwie to mnie tu zaprowadziło…
izomorfizm
1
możesz spróbować analizy danych, ponieważ kilka umysłów statystycznych ma doświadczenie w programowaniu danych o wielu wymiarach.
aeroNotAuto
2
AKTUALIZACJA: Od wersji 4.6-9 randomForestmoże obsługiwać predyktory jakościowe z maksymalnie 53 poziomami. Wiadomości
Ben
W jaki sposób losowy las R determinuje liczbę poziomów? Chyba poziom oznacza kategorie.
ajp

Odpowiedzi:

25

W rzeczywistości jest to dość rozsądne ograniczenie, ponieważ podział na czynnik z poziomami jest w rzeczywistości wyborem jednej z 2 N - 2 możliwych kombinacji. Więc nawet przy N jak 25 przestrzeń kombinacji jest tak duża, że ​​takie wnioskowanie ma niewielki sens.N.2)N.-2)N.

Większość innych implementacji po prostu traktuje czynnik jako porządek porządkowy (tj. Liczby całkowite od 1 do ), i jest to jedna z opcji, w jaki sposób rozwiązać ten problem. W rzeczywistości RF jest często wystarczająco mądry, aby podzielić to na dowolne grupy z kilkoma podziałami.N.

Inną opcją jest zmiana reprezentacji - być może twój wynik nie zależy bezpośrednio od podmiotu stanu, ale na przykład obszar, populację, liczbę drzew sosny na mieszkańca lub inne atrybuty, które możesz zamiast tego podłączyć do swojego systemu informacyjnego.

Może być również tak, że każdy stan jest tak odizolowanym i nieskorelowanym bytem, ​​że wymaga dla siebie osobnego modelu.

Grupowanie na podstawie decyzji jest prawdopodobnie złym pomysłem, ponieważ w ten sposób przemycasz informacje z decyzji do atrybutów, co często kończy się przeregulowaniem.


źródło
4
Można go łatwo przenosić, choć w nieco żmudny sposób. Na przykład, jeśli masz od 33 do 1024 poziomów, utwórz dwa współczynniki o wartości <= 32 poziomy.
KalEl
15

Głównym powodem jest sposób implementacji randomForest. Wdrożenie od R w dużej mierze wynika ze specyfikacji oryginalnego Breimana. Należy tutaj zauważyć, że w przypadku zmiennych czynnikowych / kategorialnych kryteria podziału są binarne, z niektórymi wartościami etykiet po lewej stronie, a pozostałymi wartościami etykiet po prawej.

01[0;2)M.-1]

Dlaczego implementacje Weka i Python działają?

Implementacja weka domyślnie nie używa drzew CART. Wykorzystuje drzewa C45, które nie mają tego problemu obliczeniowego, ponieważ dla danych jakościowych dzieli się na wiele węzłów, po jednym dla każdej wartości poziomu.

Losowa implementacja lasu w Pythonie nie może używać zmiennych kategorialnych / czynnikowych. Musisz zakodować te zmienne w zmienne fikcyjne lub zmienne numeryczne.

M.

rapaio
źródło
2
Wielkie dzięki! Czy z twojej odpowiedzi wynika, że ​​implementacja R w leczeniu wartości kategorycznych jest lepsza niż w Pythonie (pamiętam, że Max Kuhn wspominał, że grupowanie zmiennych kategorialnych dla RF zapewnia nieco lepsze wyniki niż ich zmiękczanie), lub przynajmniej uruchomienie Losowego Lasu w R vs Python Mam bardzo dużą szansę na uzyskanie różnych wyników (dokładności itp.)? Czy na podstawie własnego doświadczenia, podczas modelowania, ma sens wypróbowanie obu grupowania zmiennych (w R) i ich zmumifikowanie, a następnie porównanie dwóch podejść?
Sergey Bushmanov,
2
Kodowanie atrapy działa, ale może wygenerować tylko jedną kategorię względem wszystkich. Po kodowaniu zmienne są testowane pojedynczo. Tak więc niemożliwe jest wdrożenie twoinging. Jeśli ta funkcja może pomóc, myślę, że praktycznie nie ma dużych różnic. Istnieją jednak inne rzeczy, które mogą wymagać uwagi podczas pracy ze zmiennym znaczeniem: niektóre implementacje są tendencyjne do jakościowego z wieloma poziomami. Szczegółowe informacje można znaleźć w dokumentach Carolin Strobl: statistik.uni-dortmund.de/useR-2008/slides/Strobl+Zeileis.pdf . W R są pewne implementacje, które nie mają tego błędu.
rapaio
2

Możesz spróbować przedstawić tę kolumnę inaczej. Możesz reprezentować te same dane, co rzadka ramka danych.

Minimalny wykonalny kod;

example <- as.data.frame(c("A", "A", "B", "F", "C", "G", "C", "D", "E", "F"))
names(example) <- "strcol"

for(level in unique(example$strcol)){
      example[paste("dummy", level, sep = "_")] <- ifelse(example$strcol == level,     1, 0)
}

Zauważ, że każda wartość w oryginalnej kolumnie staje się teraz osobną kolumną zastępczą.

Bardziej obszerny przykładowy kod;

set.seed(0)
combs1 = sample.int(33, size= 10000, replace=TRUE)
combs2 = sample.int(33, size= 10000, replace=TRUE)
combs3 = combs1 * combs2 + rnorm(10000,mean=0,100)
df_hard = data.frame(y=combs3, first=factor(combs1), second=factor(combs2))

for(level in unique(df_hard$first)){
    df_hard[paste("first", level, sep = "_")] <- ifelse(df_hard$first == level, 1, 0)
}

for(level in unique(df_hard$second)){
    df_hard[paste("second", level, sep = "_")] <- ifelse(df_hard$second == level, 1, 0)
}

example$first <- NULL
example$second <- NULL

rf_mod = randomForest( y ~ ., data=example )

Chociaż ten fragment kodu pokazuje, że rzeczywiście nie będziesz już otrzymywać błędu, zauważysz, że algorytm randomForest potrzebuje teraz dużo czasu, zanim się skończy. Wynika to z ograniczenia procesora, więc możesz teraz zmapować to zadanie poprzez próbkowanie.

Aby uzyskać więcej informacji, sprawdź ten post na blogu:

https://blog.cloudera.com/blog/2013/02/how-to-resample-from-a-large-data-set-in-parallel-with-r-on-hadoop/

Vincent Warmerdam
źródło
Drugi blok kodu wygląda na mylący, chociaż używasz df_hard w całym ciele, w ostatnich wierszach ustawiasz „first” i „second” na NULL, a także używasz „example” jako danych dla randomForest nie ma sensu, aby ja, ponieważ nie ma związku między przykładem a df_hard.
Özgür
Vincent, czy nie uważasz, że skończę z tak dużymi problemami, jeśli mam poziomy rzędu 100+, czy sugerujesz dodanie każdej kolumny jako danych losowych?
Hardik Gupta
Inną alternatywą jest użycie losowej implementacji w H2O; ma to lepszą obsługę dużych zestawów danych. Nie rozumiem bitu „dodaj każdą kolumnę jako dane wejściowe do losowego” bitu.
Vincent Warmerdam
0

Zamiast tego możesz użyć pakietu extraTrees. Algorytm skrajnie losowych lasów nie próbuje żadnego punktu przerwania / podziału, a jedynie ograniczony losowy podzbiór podziałów.

Soren Havelund Welling
źródło
1
extraTrees ma ograniczenia w tym sensie, że dane wejściowe muszą być macierzą danych liczbowych, prawda?
Hardik Gupta
0

Inna opcja: w zależności od liczby poziomów i liczby obserwacji w danych możesz połączyć niektóre poziomy. Poza przekroczeniem limitu może zmniejszyć wariancję, jeśli masz wiele poziomów z zaledwie kilkoma obserwacjami. Hadley „s Forcats: fct_lump to robi.

Scott Kaiser
źródło