По-перше, я хотів би уточнити, наскільки насправді визначається метрика важливості.
MeanDecreaseGini - це міра змінної важливості, заснована на індексі домішки Джині, який використовується для обчислення розщеплення під час тренувань. Поширена помилкова думка полягає в тому, що показник важливості змінної стосується Джині, який використовується для затвердження продуктивності моделі, яка тісно пов'язана з AUC, але це неправильно. Ось пояснення з пакету randomForest, написаного Брейманом та Катлером:
Важливість Джині
Кожного разу, коли розбиття вузла робиться на змінну m, критерій домішки Джині для двох нащадкових вузлів є меншим, ніж батьківський вузол. Додавання зменшення джині для кожної окремої змінної для всіх дерев у лісі надає важливої змінної швидкості, яка часто дуже відповідає мірі важливості перестановки.
Індекс домішки Джині визначається як
Де - кількість класів у цільовій змінній, а - відношення цього класу.
G=∑i=1ncpi(1−pi)
ncpi
Для двох класових задач це призводить до наступної кривої, яка максимально розрахована на вибірку 50-50 і мінімізована для однорідних множин:
Потім важливість обчислюється як
усереднене всіх розщеплень у лісі за участю відповідного передбачувача. Оскільки це середнє значення, його можна легко розширити до усереднення по всіх розбиттям змінних, що містяться в групі.
I=Gparent−Gsplit1−Gsplit2
Придивившись ближче, ми знаємо, що кожна змінна важливість є середньою умовою використовуваної змінної, і середнє значення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