Losowy las z klasami, które są bardzo niezrównoważone

Używam losowych lasów w problemie big data, który ma bardzo niezrównoważoną klasę odpowiedzi, więc przeczytałem dokumentację i znalazłem następujące parametry:

strata 

sampsize

Dokumentacja tych parametrów jest niewielka (lub nie miałem szczęścia jej znaleźć) i naprawdę nie rozumiem, jak ją zaimplementować. Używam następującego kodu:

randomForest(x=predictors, 
             y=response, 
             data=train.data, 
             mtry=lista.params[1], 
             ntree=lista.params[2], 
             na.action=na.omit, 
             nodesize=lista.params[3], 
             maxnodes=lista.params[4],
             sampsize=c(250000,2000), 
             do.trace=100, 
             importance=TRUE)

Odpowiedź jest klasą z dwoma możliwymi wartościami, pierwsza pojawia się częściej niż druga (10000: 1 lub więcej)

list.params jest listą o różnych parametrach (duh! Wiem...)

Cóż, pytanie (znowu) brzmi: Jak mogę użyć parametru 'warstwy'? Używam poprawnie sampsize?

I wreszcie, czasami dostaję następujący błąd:

Error in randomForest.default(x = predictors, y = response, data = train.data,  :
  Still have fewer than two classes in the in-bag sample after 10 attempts.
Przepraszam, jeśli zadaję tyle (i może głupich) pytań ...
Author: joran, 2012-01-02

4 answers

Należy spróbować użyć metod pobierania próbek, które zmniejszają stopień nierównowagi z 1: 10,000 do 1: 100 lub 1: 10. Należy również zmniejszyć rozmiar generowanych drzew. (W tej chwili są to zalecenia, które powtarzam tylko z pamięci, ale zobaczę, czy uda mi się wyśledzić więcej autorytetu niż moja gąbczasta kora.)

Jednym ze sposobów zmniejszenia rozmiaru drzew jest ustawienie" nodesize " większego. Przy takim stopniu nierównowagi może być konieczne, aby rozmiar węzła był naprawdę duży, powiedzmy 5-10 tys. Oto wątek w rhelp: https://stat.ethz.ch/pipermail/r-help/2011-September/289288.html

W obecnym stanie pytania masz sampsize=c(250000,2000), natomiast ja bym pomyślał, że coś takiego jak sampsize = c (8000,2000), jest bardziej zgodne z moimi sugestiami. Myślę, że tworzysz próbki, w których nie masz żadnej z grupy, która została pobrana tylko z 2000.

 6
Author: 42-,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-02 23:47:52

Jest kilka opcji.

Jeśli masz dużo danych, odłóż losową próbkę danych. Zbuduj swój model na jednym zestawie, a następnie użyj drugiego do określenia właściwego odcięcia dla prawdopodobieństwa klasy za pomocą krzywej ROC.

Można również upsamplować dane w klasie mniejszości. Algorytm SMOTE może pomóc(Zobacz odniesienie poniżej i pakiet DMwR dla funkcji).

Możesz również użyć innych technik. rpart() i kilka innych funkcji pozwala na różne koszty o błędach, żebyś mógł bardziej faworyzować klasę mniejszościową. Możesz zapakować ten typ modelu rpart() w celu przybliżenia tego, co robi losowy Las.

ksvm() w pakiecie kernlab można również użyć niezrównoważonych kosztów (ale szacunki prawdopodobieństwa nie są już dobre, gdy to robisz). Wiele innych pakietów posiada argumenty pozwalające na ustawienie priorów. Możesz również dostosować to, aby położyć większy nacisk na klasę mniejszościową.

[3]}ostatnia myśl: maksymalizacja modeli w oparciu o dokładność nie przyniesie Ci gdziekolwiek (można uzyskać 99.99% off the bat). Karetka może dostroić modele w oparciu o statystyki Kappa, co jest znacznie lepszym wyborem w Twoim przypadku.
 4
Author: topepo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-03 05:28:41

Przepraszam, Nie wiem jak dodać komentarz do wcześniejszej odpowiedzi, więc stworzę osobną odpowiedź.

Przypuszczam, że problem jest spowodowany dużą nierównowagą zbioru danych (zbyt mało przypadków jednej z klas jest obecnych). Dla każdego drzewa w RF algorytm tworzy próbkę bootstrap, która jest zestawem treningowym dla tego drzewa. A jeśli masz zbyt mało przykładów jednej z klas w zbiorze danych, to próbkowanie bootstrap wybierze przykłady tylko jednej klasy (major class). I tak drzewo nie może być uprawiane tylko na jednym przykładzie klasy. Wydaje się, że istnieje limit na 10 nieudanych prób próbkowania. Tak więc propozycja Dwina, aby zmniejszyć stopień nierównowagi do niższych wartości (1:100 lub 1: 10) jest najbardziej rozsądna.

 3
Author: DrDom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-03 08:50:05

Całkiem pewien, że nie zgadzam się z pomysłem usunięcia obserwacji z próbki.

Zamiast tego możesz rozważyć użycie próbki warstwowej, aby ustawić stały procent każdej klasy za każdym razem, gdy jest ona ponownie próbkowana. Można to zrobić za pomocą pakietu karetki. W ten sposób nie będziesz pomijał obserwacji, zmniejszając rozmiar próbki treningowej. Nie pozwoli Ci to na reprezentowanie swoich klas, ale upewni się, że każda podpróbka ma reprezentatywną próbkę.

Oto przykład, który znalazłem:

len_pos <- nrow(example_dataset[example_dataset$target==1,])
len_neg <- nrow(example_dataset[example_dataset$target==0,])

train_model <- function(training_data, labels, model_type, ...) {
  experiment_control <- trainControl(method="repeatedcv",
                                     number = 10,
                                     repeats = 2,
                                     classProbs = T,
                                     summaryFunction = custom_summary_function)
  train(x = training_data,
        y = labels,
        method = model_type,
        metric = "custom_score",
        trControl = experiment_control,
        verbose = F,
        ...)
}

# strata refers to which feature to do stratified sampling on.
# sampsize refers to the size of the bootstrap samples to be taken from each class. These samples will be taken as input
# for each tree. 

fit_results <- train_model(example_dataset
                           , as.factor(sprintf("c%d", as.numeric(example_dataset$target)))        
                           ,"rf"
                           ,tuneGrid = expand.grid(mtry = c( 3,5,10))
                           ,ntree=500
                           ,strata=as.factor(example_dataset$target)
                           ,sampsize = c('1'=as.integer(len_pos*0.25),'0'=as.integer(len_neg*0.8))
)
 1
Author: mmann1123,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 14:56:32