Względne znaczenie zestawu predyktorów w losowej klasyfikacji lasów w R.

31

Chciałbym określić względną ważność zbiorów zmiennych w stosunku do randomForestmodelu klasyfikacji w R. importanceFunkcja zapewnia MeanDecreaseGinimetrykę dla każdego predyktora - czy jest to tak proste, jak sumowanie tego dla każdego predyktora w zestawie?

Na przykład:

# Assumes df has variables a1, a2, b1, b2, and outcome
rf <- randomForest(outcome ~ ., data=df)
importance(rf)
# To determine whether the "a" predictors are more important than the "b"s,
# can I sum the MeanDecreaseGini for a1 and a2 and compare to that of b1+b2?
Max Ghenis
źródło

Odpowiedzi:

46

Najpierw chciałbym wyjaśnić, co faktycznie mierzy wskaźnik ważności.

MeanDecreaseGini jest miarą o różnym znaczeniu opartym na wskaźniku zanieczyszczenia Gini stosowanym do obliczania podziałów podczas treningu. Powszechnym nieporozumieniem jest to, że metryka o zmiennym znaczeniu odnosi się do Giniego używanego do zapewnienia wydajności modelu, która jest ściśle związana z AUC, ale jest to błędne. Oto wyjaśnienie z pakietu randomForest napisanego przez Breimana i Cutlera:

Znaczenie Gini
Za każdym razem, gdy dokonuje się podziału węzła na zmiennej m, kryterium zanieczyszczenia gini dla dwóch potomnych węzłów jest mniejsze niż węzeł nadrzędny. Zsumowanie spadków gini dla każdej pojedynczej zmiennej we wszystkich drzewach w lesie daje szybkie znaczenie zmiennej, które często jest bardzo spójne z miarą ważności permutacji.

Wskaźnik zanieczyszczenia Giniego jest zdefiniowana jako

sol=ja=1ndopja(1-pja)
ndopja

W przypadku problemu dwóch klas powoduje to następującą krzywą, która jest zmaksymalizowana dla próbki 50-50 i zminimalizowana dla zestawów jednorodnych: Zanieczyszczenie Gini dla 2 klasy

Ważność jest następnie obliczana jako

ja=solpzarmint-solspljat1-solspljat2)

mi[mi[X|Y]]=mi[X]

Teraz, aby bezpośrednio odpowiedzieć na twoje pytanie nie tak proste, jak tylko podsumowując wszystkie importances w każdej grupie, aby uzyskać łączną MeanDecreaseGini ale obliczenia średniej ważonej będzie Ci odpowiedź szukasz. Musimy tylko znaleźć zmienne częstotliwości w każdej grupie.

Oto prosty skrypt, aby pobrać je z losowego obiektu lasu w R:

var.share <- function(rf.obj, members) {
  count <- table(rf.obj$forest$bestvar)[-1]
  names(count) <- names(rf.obj$forest$ncat)
  share <- count[members] / sum(count[members])
  return(share)
}

Wystarczy podać nazwy zmiennych w grupie jako parametr członkowie.

Mam nadzieję, że to odpowiada na twoje pytanie. Potrafię napisać funkcję, aby uzyskać bezpośrednio ważność grupy, jeśli jest to interesujące.

EDYCJA:
Oto funkcja, która nadaje grupie znaczenie nadane randomForestobiektowi i liście wektorów o nazwach zmiennych. Używa var.sharejak wcześniej zdefiniowano. Nie sprawdziłem danych wejściowych, dlatego musisz upewnić się, że używasz odpowiednich nazw zmiennych.

group.importance <- function(rf.obj, groups) {
  var.imp <- as.matrix(sapply(groups, function(g) {
    sum(importance(rf.obj, 2)[g, ]*var.share(rf.obj, g))
  }))
  colnames(var.imp) <- "MeanDecreaseGini"
  return(var.imp)
}

Przykład użycia:

library(randomForest)                                                          
data(iris)

rf.obj <- randomForest(Species ~ ., data=iris)

groups <- list(Sepal=c("Sepal.Width", "Sepal.Length"), 
               Petal=c("Petal.Width", "Petal.Length"))

group.importance(rf.obj, groups)

>

      MeanDecreaseGini
Sepal         6.187198
Petal        43.913020

Działa również w przypadku nakładających się grup:

overlapping.groups <- list(Sepal=c("Sepal.Width", "Sepal.Length"), 
                           Petal=c("Petal.Width", "Petal.Length"),
                           Width=c("Sepal.Width", "Petal.Width"), 
                           Length=c("Sepal.Length", "Petal.Length"))

group.importance(rf.obj, overlapping.groups)

>

       MeanDecreaseGini
Sepal          6.187198
Petal         43.913020
Width          30.513776
Length        30.386706
podczas
źródło
Dzięki za jasną i rygorystyczną odpowiedź! Jeśli nie miałbyś nic przeciwko dodaniu funkcji do importów grupowych, byłoby świetnie.
Max Ghenis,
Dzięki za odpowiedź! Dwa pytania, jeśli masz minutę: (1) Znaczenie jest następnie obliczane jako ... : w odniesieniu do definicji Breimana, jestem tam „spadkiem gini”, a ważność byłaby sumą spadków, prawda ? (2) uśrednione dla wszystkich podziałów w lesie obejmujących dany predyktor : Czy mogę zastąpić to przez wszystkie węzły obejmujące podział na tę konkretną cechę ? Na pewno w pełni rozumiem;)
Remi Mélisson
1
Twój komentarz sprawił, że zastanowiłem się trochę nad definicjami, więc przekopałem losowy kod użyty w R, aby poprawnie odpowiedzieć. Szczerze mówiąc, byłem trochę zaniedbany. Średnia jest obliczana dla wszystkich drzew, a nie wszystkich węzłów. Zaktualizuję odpowiedź, jak tylko będę miał na to czas. Oto odpowiedzi na twoje pytanie: (1) tak. Tak to jest zdefiniowane na poziomie drzewa. Suma spadków jest następnie uśredniana dla wszystkich drzew. (2) Tak właśnie chciałem powiedzieć, ale tak naprawdę nie ma to miejsca.
zaś
4

Funkcja zdefiniowana powyżej jako G = suma nad klasami [pi (1-pi)] jest w rzeczywistości entropią, która jest innym sposobem oceny podziału. Różnica między entropią w węzłach potomnych i węźle nadrzędnym polega na uzyskaniu informacji. Funkcja zanieczyszczenia GINI wynosi G = 1 - suma ponad klasy [pi ^ 2].

Sowmya Iyer
źródło