Losowy las: jak obsługiwać nowe poziomy czynników w zestawie testowym?

13

Próbuję przewidzieć przy użyciu losowego modelu lasu w R.

Jednak dostaję błędy, ponieważ niektóre czynniki mają inne wartości w zestawie testowym niż w zestawie treningowym. Na przykład czynnik Cat_2ma wartości 34, 68, 76itp. W zestawie testowym, które nie pojawiają się w zestawie szkoleniowym. Niestety nie mam kontroli nad zestawem testowym ... muszę go używać tak, jak jest.

Moim jedynym obejściem było przekonwertowanie problematycznych czynników z powrotem na wartości liczbowe przy użyciu as.numeric(). To działa , ale nie jestem bardzo zadowolony, ponieważ wartości te są kody, które nie mają sensu liczbowej ...

Czy uważasz, że byłoby inne rozwiązanie, aby usunąć nowe wartości z zestawu testowego? Ale bez usuwania wszystkich innych wartości czynników (powiedzmy wartości 1, 2, 14, 32itp.), Które są zarówno w trakcie szkolenia, jak i testu, i zawierają informacje potencjalnie przydatne do prognoz.

Benoit_Plante
źródło
1
Rozumiem, dlaczego wartości w teście musiałyby znajdować się w zestawie treningowym. Ideą klasyfikacji jest wykorzystanie danych treningowych, aby dowiedzieć się, jak wyglądają gęstości warunkowe w klasie. Nie widzisz każdej możliwej wartości z gęstości. Jeśli zmienna jest używana w drzewie podziału, wówczas podział określa, którą gałąź należy zastosować dla wszelkich niewidocznych wartości, a także tych, które zostały zaobserwowane.
Michael R. Chernick
Podajesz prawidłowy punkt, ale na poziomie praktycznym za pomocą konkretnego narzędzia zapytanego o (pakiet RF w R) jest to niedozwolone. Moja odpowiedź na temat przypisania jest jednym z rozwiązań, choć z pewnością nie najlepszym rozwiązaniem. Czy przynajmniej powoduje, że kod nie ulega awarii, więc przynajmniej działa dla małych wartości pracy.
Bogdanovist
Podobnie do mojego pytania tutaj: stats.stackexchange.com/questions/18004/… . Myślę, że mógłbym użyć GBM zamiast RF, ponieważ wydaje się, że lepiej radzi sobie z nowymi poziomami czynników. Czy przyjrzałeś się także implementacji RF na imprezie? Nigdy nie lubiłem randomForest z powodu tych problemów (i niemożności płynnego radzenia sobie z brakującymi wartościami).
B_Miner

Odpowiedzi:

2

Jeśli zestaw testowy ma wiele tych punktów z nowymi wartościami współczynników, nie jestem pewien, jakie jest najlepsze podejście. Jeśli jest to tylko garść punktów, być może uda ci się uciec od czegoś tak niepotrzebnego, jak potraktowanie błędnych poziomów czynników jako brakujących danych i przypisanie ich dowolnemu podejściu, które uznasz za stosowne. Implementacja R ma kilka sposobów przypisywania brakujących danych, wystarczy ustawić te poziomy czynników na NA, aby wskazać, że brakuje.

Bogdanovist
źródło
8

King i Bonoit , ten fragment kodu może być użyteczny do zharmonizowania poziomów:

for(attr in colnames(training))
{
  if (is.factor(training[[attr]]))
  {
    new.levels <- setdiff(levels(training[[attr]]), levels(testing[[attr]]))
    if ( length(new.levels) == 0 )
    { print(paste(attr, '- no new levels')) }
    else
    {
      print(c(paste(attr, length(new.levels), 'of new levels, e.g.'), head(new.levels, 2)))
      levels(testing[[attr]]) <- union(levels(testing[[attr]]), levels(training[[attr]]))
    }
  }
}

Drukuje także, które atrybuty są zmieniane. Nie znalazłem dobrego sposobu na napisanie go bardziej elegancko (z płynnością czy coś takiego). Wszelkie wskazówki są mile widziane.

użytkownik41330
źródło
4

Oto kod, który napisałem, który adresuje odpowiedź @ King powyżej. Naprawiono błąd:

# loops through factors and standardizes the levels
for (f in 1:length(names(trainingDataSet))) {
    if (levels(testDataSet[,f]) > levels(trainingDataSet[,f])) {    
            levels(testDataSet[,f]) = levels(trainingDataSet[,f])       
    } else {
            levels(trainingDataSetSMOTEpred[,f]) = levels(testDataSet[,f])      
    }
}
Ifarb
źródło
cześć @ifarb, próbuję zrozumieć twoje rozwiązanie: co to jest trainingDataSetSMOTEpred i gdzie jest zdefiniowane w kodzie?
Kasia Kulma
3

Zestaw testowy i treningowy należy połączyć jako jeden zestaw, a następnie zmienić poziomy zestawu treningowego. Moje kody to:

totalData <- rbind(trainData, testData)
for (f in 1:length(names(totalData))) {
  levels(trainData[, f]) <- levels(totalData[, f])
}

Działa to w każdym przypadku, gdy liczba poziomów w teście jest większa lub mniejsza niż szkolenie.

Cscode Li
źródło
2

Mam kiepskie obejście, gdy używam randomForest w R. Prawdopodobnie nie jest to teoretycznie rozsądne, ale działa.

levels(testSet$Cat_2) = levels(trainingSet$Cat_2)

lub na odwrót. Zasadniczo daje po prostu powiedzieć R, że jest to poprawna wartość, tylko że istnieją 0 przypadków; więc przestań mnie denerwować z powodu błędu.

Nie jestem wystarczająco inteligentny, aby kodować go tak, aby automatycznie wykonywał akcję dla wszystkich funkcji jakościowych. Wyślij mi kod, jeśli wiesz jak ...

Król
źródło
Ale to nie działa, jeśli liczba poziomów w teście jest większa niż szkolenie. Działa tylko wtedy, gdy poziomy współczynnika danych testowych wynoszą <= poziomy współczynnika danych treningowych.
KarthikS
1

Jestem pewien, że pomyślałbyś o tym już, gdyby tak było, ale jeśli zestaw testowy ma rzeczywiste wartości i używasz zestawu testowego do celów krzyżowej weryfikacji, to ponownie dzieląc ramkę danych na szkoleniowe i testowe ramki danych gdy oba są zrównoważone na tych czynnikach, uniknąłby twojego problemu. Ta metoda jest powszechnie znana jako warstwowa walidacja krzyżowa .

Goldisfine
źródło