Bosques aleatorios son apenas una caja negra. Están basados en árboles de decisión, que son muy fáciles de interpretar:
#Setup a binary classification problem
require(randomForest)
data(iris)
set.seed(1)
dat <- iris
dat$Species <- factor(ifelse(dat$Species=='virginica','virginica','other'))
trainrows <- runif(nrow(dat)) > 0.3
train <- dat[trainrows,]
test <- dat[!trainrows,]
#Build a decision tree
require(rpart)
model.rpart <- rpart(Species~., train)
Esto se traduce en un simple árbol de decisión:
> model.rpart
n= 111
node), split, n, loss, yval, (yprob)
* denotes terminal node
1) root 111 35 other (0.68468468 0.31531532)
2) Petal.Length< 4.95 77 3 other (0.96103896 0.03896104) *
3) Petal.Length>=4.95 34 2 virginica (0.05882353 0.94117647) *
Si Pétalo.Longitud < 4.95, este árbol clasifica a la observación como "otros". Si es mayor que 4.95, clasifica a la observación como "virginica." Un bosque aleatorio simple es una colección de muchos árboles, donde cada uno está entrenado en un subconjunto aleatorio de los datos. Cada árbol, a continuación, "votos" en la clasificación final de cada observación.
model.rf <- randomForest(Species~., train, ntree=25, proximity=TRUE, importance=TRUE, nodesize=5)
> getTree(model.rf, k=1, labelVar=TRUE)
left daughter right daughter split var split point status prediction
1 2 3 Petal.Width 1.70 1 <NA>
2 4 5 Petal.Length 4.95 1 <NA>
3 6 7 Petal.Length 4.95 1 <NA>
4 0 0 <NA> 0.00 -1 other
5 0 0 <NA> 0.00 -1 virginica
6 0 0 <NA> 0.00 -1 other
7 0 0 <NA> 0.00 -1 virginica
Usted puede incluso tirar de árboles individuales de la rf, y un vistazo a su estructura. El formato es ligeramente diferente a la de rpart
modelos, pero usted podría inspeccionar cada árbol, si usted quería y ver cómo es el modelado de los datos.
Además, ningún modelo es realmente una caja negra, porque puede examinar las respuestas de la predicción vs real las respuestas de cada variable en el conjunto de datos. Esta es una buena idea, independientemente de qué tipo de modelo que se está construyendo:
library(ggplot2)
pSpecies <- predict(model.rf,test,'vote')[,2]
plotData <- lapply(names(test[,1:4]), function(x){
out <- data.frame(
var = x,
type = c(rep('Actual',nrow(test)),rep('Predicted',nrow(test))),
value = c(test[,x],test[,x]),
species = c(as.numeric(test$Species)-1,pSpecies)
)
out$value <- out$value-min(out$value) #Normalize to [0,1]
out$value <- out$value/max(out$value)
out
})
plotData <- do.call(rbind,plotData)
qplot(value, species, data=plotData, facets = type ~ var, geom='smooth', span = 0.5)
He normalizado de las variables (sépalos y pétalos de longitud y anchura) para un rango 0-1. La respuesta también es de 0 a 1, donde 0 es el otro y 1 es virginica. Como se puede ver el bosque aleatorio es un buen modelo, incluso en el conjunto de prueba.
Además, un bosque aleatorio calculará diversos medida de importancia variable, que puede ser muy informativo:
> importance(model.rf, type=1)
MeanDecreaseAccuracy
Sepal.Length 0.28567162
Sepal.Width -0.08584199
Petal.Length 0.64705819
Petal.Width 0.58176828
Esta tabla representa la eliminación de cada variable, se reduce la precisión del modelo. Por último, hay muchas otras parcelas usted puede hacer de un bosque aleatorio del modelo, para ver lo que está pasando en la caja negra:
plot(model.rf)
plot(margin(model.rf))
MDSplot(model.rf, iris$Species, k=5)
plot(outlier(model.rf), type="h", col=c("red", "green", "blue")[as.numeric(dat$Species)])
Usted puede ver los archivos de ayuda para cada una de estas funciones para obtener una mejor idea de lo que muestran.