Відносна важливість набору предикторів у випадковій класифікації лісів у R


31

Я хотів би визначити відносну важливість наборів змінних до randomForestкласифікаційної моделі в Р. importanceФункція забезпечує MeanDecreaseGiniметрику для кожного окремого предиктора - чи це так просто, як підсумовувати це для кожного предиктора в наборі?

Наприклад:

# 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?

Відповіді:


46

По-перше, я хотів би уточнити, наскільки насправді визначається метрика важливості.

MeanDecreaseGini - це міра змінної важливості, заснована на індексі домішки Джині, який використовується для обчислення розщеплення під час тренувань. Поширена помилкова думка полягає в тому, що показник важливості змінної стосується Джині, який використовується для затвердження продуктивності моделі, яка тісно пов'язана з AUC, але це неправильно. Ось пояснення з пакету randomForest, написаного Брейманом та Катлером:

Важливість Джині
Кожного разу, коли розбиття вузла робиться на змінну m, критерій домішки Джині для двох нащадкових вузлів є меншим, ніж батьківський вузол. Додавання зменшення джині для кожної окремої змінної для всіх дерев у лісі надає важливої ​​змінної швидкості, яка часто дуже відповідає мірі важливості перестановки.

Індекс домішки Джині визначається як Де - кількість класів у цільовій змінній, а - відношення цього класу.

G=i=1ncpi(1pi)
ncpi

Для двох класових задач це призводить до наступної кривої, яка максимально розрахована на вибірку 50-50 і мінімізована для однорідних множин: Домішки Джині для 2 класу

Потім важливість обчислюється як усереднене всіх розщеплень у лісі за участю відповідного передбачувача. Оскільки це середнє значення, його можна легко розширити до усереднення по всіх розбиттям змінних, що містяться в групі.

I=GparentGsplit1Gsplit2

Придивившись ближче, ми знаємо, що кожна змінна важливість є середньою умовою використовуваної змінної, і середнє значенняDecreaseGini групи було б просто середнім значенням цих імпортів, зваженим на частку, яку ця змінна використовується в лісі порівняно з іншими змінними цієї ж групи. Це справедливо, тому що властивість вежі

E[E[X|Y]]=E[X]

Тепер безпосередньо відповісти на ваше запитання не так просто, як просто підсумовувати всі імпорти в кожній групі, щоб отримати комбінований MeanDecreaseGini, але обчислення середньозваженого рівня отримає відповідь, яку ви шукаєте. Нам просто потрібно знайти змінні частоти в межах кожної групи.

Ось простий скрипт, щоб отримати їх від випадкового лісового об’єкта в 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)
}

Просто введіть імена змінних у групі як параметр members.

Я сподіваюся, що це відповість на ваше запитання. Я можу записати функцію для безпосереднього отримання групових імпортів, якщо це представляє інтерес.

EDIT:
Ось функція, яка надає групової важливості даному randomForestоб'єкту та списку векторів зі змінними іменами. Він використовує, var.shareяк було визначено раніше. Я не робив жодної перевірки введення, тому вам потрібно переконатися, що ви використовуєте правильні імена змінних.

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)
}

Приклад використання:

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

Він також працює для груп, що перекриваються:

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

Дякуємо за чітку та сувору відповідь! Якщо ви не проти додати функцію для групових імпортів, це було б чудово.
Макс Ghenis

Дякую за цю відповідь! Два питання, якщо у вас є хвилина: (1) Важливість тоді обчислюється як ... : щодо визначення Бреймана, я є "зменшенням джині" там, і важливим буде сума зменшення, правильно ? (2) усереднене для всіх розщеплень у лісі за участю відповідного передбачувача : Чи можу я замінити це всіма вузлами, що містять розкол на цю особливість ? Щоб бути впевненим, я повністю розумію;)
Ремі Меліссон

1
Ваш коментар змусив мене трохи більше подумати над визначеннями, тому я переглянув код randomForest, який використовується в R, щоб правильно відповісти на нього. Я був трохи відвертий, щоб бути чесним. Середня величина складає всі дерева та не всі вузли. Я оновлю відповідь, як тільки отримаю час на неї. Ось відповіді на ваше запитання на даний момент: (1) так. Ось як це визначено на рівні дерева. Потім сума зменшення усереднюється по всіх деревах. (2) Так, саме це я хотів сказати, але це насправді не відповідає.
поки

4

Функція, визначена вище як G = сума по класах [pi (1-pi)], насправді є ентропією, що є ще одним способом оцінки розбиття. Різниця між ентропією в дитячих вузлах і батьківським вузлом - це посилення інформації. Функція домішки GINI становить G = 1- сума по класах [pi ^ 2].

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.