¿Cómo `predic.randomForest` estima las probabilidades de clase?

15

¿Cómo randomForestcalcula el paquete las probabilidades de clase cuando lo uso predict(model, data, type = "prob")?

Estaba usando rangerpara entrenar bosques al azar usando el probability = Targumento para predecir probabilidades. rangerdice en la documentación que:

Cultivar un bosque de probabilidad como en Malley et al. (2012)

Simulé algunos datos, probé ambos paquetes y obtuve resultados muy diferentes (vea el código a continuación)

ingrese la descripción de la imagen aquí

Entonces sé que usa una técnica diferente (entonces guardabosques) para estimar las probabilidades. ¿Pero cual?

simulate_data <- function(n){
  X <- data.frame(matrix(runif(n*10), ncol = 10))
  Y <- data.frame(Y = rbinom(n, size = 1, prob = apply(X, 1, sum) %>%
                               pnorm(mean = 5)
                             ) %>% 
                    as.factor()

  ) 
  dplyr::bind_cols(X, Y)
}

treino <- simulate_data(10000)
teste <- simulate_data(10000)

library(ranger)
modelo_ranger <- ranger(Y ~., data = treino, 
                                num.trees = 100, 
                                mtry = floor(sqrt(10)), 
                                write.forest = T, 
                                min.node.size = 100, 
                                probability = T
                                )

modelo_randomForest <- randomForest(Y ~., data = treino,
                                    ntree = 100, 
                                    mtry = floor(sqrt(10)),
                                    nodesize = 100
                                    )

pred_ranger <- predict(modelo_ranger, teste)$predictions[,1]
pred_randomForest <- predict(modelo_randomForest, teste, type = "prob")[,2]
prob_real <- apply(teste[,1:10], 1, sum) %>% pnorm(mean = 5)

data.frame(prob_real, pred_ranger, pred_randomForest) %>%
  tidyr::gather(pacote, prob, -prob_real) %>%
  ggplot(aes(x = prob, y = prob_real)) + geom_point(size = 0.1) + facet_wrap(~pacote)
Daniel Falbel
fuente
1
Solo por curiosidad, ¿cuál sería prob_real?
Firebug
1
La probabilidad de respuesta real. Como esta es una simulación, tengo esto para cada observación
Daniel Falbel

Respuestas:

17

Es solo la proporción de votos de los árboles en el conjunto.

library(randomForest)

rf = randomForest(Species~., data = iris, norm.votes = TRUE, proximity = TRUE)
p1 = predict(rf, iris, type = "prob")
p2 = predict(rf, iris, type = "vote", norm.votes = TRUE)

identical(p1,p2)
#[1] TRUE

Alternativamente, si multiplica sus probabilidades por ntree, obtendrá el mismo resultado, pero ahora en recuentos en lugar de proporciones.

p1 = predict(rf, iris, type = "prob")
p2 = predict(rf, iris, type = "vote", norm.votes = FALSE)

identical(500*p1,p2)
#[1] TRUE
Firebug
fuente
2
¡Gracias! ¿Tienes alguna idea de por qué la proporción de votos es mejor que la probabilidad de los bosques? ¿O crees que esto sucede solo por este problema? Ver este enlace (en portugués)
Daniel Falbel
2
@DanielFalbel Si bien estoy bastante familiarizado con lo randomForestque no tengo mucho conocimiento ranger(de hecho, nunca lo usé), por lo que no podría responder, lo siento. Pero es una pregunta interesante, tal vez podría hacer otra pregunta sobre cómo ambas estrategias son diferentes.
Firebug
6

El Malley (2012) está disponible aquí: http://dx.doi.org/10.3414%2FME00-01-0052 . Una referencia completa está en la parte de referencias en la documentación del guardabosques.

En resumen, cada árbol predice las probabilidades de clase y estas probabilidades se promedian para la predicción del bosque. Para dos clases, esto es equivalente a un bosque de regresión en una respuesta codificada 0-1.

En contraste, en randomForestla type="prob"que cada árbol predice una clase y las probabilidades se calcularon a partir de estas clases.

En el ejemplo aquí intenté usar la distribución uniforme en lugar de la distribución normal para generar las probabilidades, y aquí el otro enfoque parece funcionar mejor. Me pregunto si estas probabilidades son realmente la verdad.

Por cierto, los mismos resultados que en el randomForestejemplo anterior se pueden lograr con el guardabosques utilizando la clasificación y el cálculo de probabilidad manual (uso predict.all=TRUEen predicción).

mnwright
fuente
puede ver que esas son las probabilidades de respuesta en el código de simulación. Mira: Y = rbinom(n, size = 1, prob = apply(X, 1, sum) %>% pnorm(mean = 5)). Así es como se genera Y, sumando X1, X2, ..., X10 y luego obteniendo el cuantil de la distribución normal con media = 5 que representa la suma. ¿Crees que esto tiene sentido?
Daniel Falbel
-1

Si desea estimaciones de probabilidad de fuera de bolsa, solo puede hacerlo en el paquete randomForest en R usando el modelo $ votes. Las otras estimaciones de probabilidad no son OOB.

Max
fuente
¿Qué es la estimación de probabilidad OOB?
user158565
Está fuera de la estimación de probabilidad de bolsa. En un bosque aleatorio, una forma de estimar la probabilidad asociada con cada clase es calcular la proporción de los árboles que votaron por cada clase. La estimación OOB haría lo mismo, pero solo contaría los votos de esos árboles de que la instancia no se usó en su entrenamiento (es decir, la instancia no estaba en la bolsa)
Max