La primera (y más fácil) solución: Si no están dispuestos a seguir con radiofrecuencia clásicos, como el implementado en Andy Liaw s randomForest
, usted puede tratar la parte del paquete que proporciona una implementación diferente de la original de RF algoritmo (uso del condicional árboles y esquema de agregación basado en unidades de peso promedio). Entonces, como se informó en este R-help post, se puede trazar un solo miembro de la lista de árboles. Parece funcionar sin problemas, por lo que puedo contar. Abajo es un dibujo de un árbol generado por cforest(Species ~ ., data=iris, controls=cforest_control(mtry=2, mincriterion=0))
.
Segundo (casi tan fácil) solución: la Mayoría de árbol de técnicas basadas en R (tree
, rpart
, TWIX
, etc.) ofrece una tree
-como la estructura para la impresión/representación gráfica de un único árbol. La idea sería convertir la salida de randomForest::getTree
a un R objeto, incluso si no tiene sentido desde un punto de vista estadístico. Básicamente, es fácil acceder a la estructura de árbol de un tree
objeto, como se muestra a continuación. Por favor, tenga en cuenta que es ligeramente diferente en función del tipo de tarea-regresión vs clasificación, donde en el último caso se añade la clase específica de probabilidades como la última columna de la obj$frame
(que es un data.frame
).
> library(tree)
> tr <- tree(Species ~ ., data=iris)
> tr
node), split, n, deviance, yval, (yprob)
* denotes terminal node
1) root 150 329.600 setosa ( 0.33333 0.33333 0.33333 )
2) Petal.Length < 2.45 50 0.000 setosa ( 1.00000 0.00000 0.00000 ) *
3) Petal.Length > 2.45 100 138.600 versicolor ( 0.00000 0.50000 0.50000 )
6) Petal.Width < 1.75 54 33.320 versicolor ( 0.00000 0.90741 0.09259 )
12) Petal.Length < 4.95 48 9.721 versicolor ( 0.00000 0.97917 0.02083 )
24) Sepal.Length < 5.15 5 5.004 versicolor ( 0.00000 0.80000 0.20000 ) *
25) Sepal.Length > 5.15 43 0.000 versicolor ( 0.00000 1.00000 0.00000 ) *
13) Petal.Length > 4.95 6 7.638 virginica ( 0.00000 0.33333 0.66667 ) *
7) Petal.Width > 1.75 46 9.635 virginica ( 0.00000 0.02174 0.97826 )
14) Petal.Length < 4.95 6 5.407 virginica ( 0.00000 0.16667 0.83333 ) *
15) Petal.Length > 4.95 40 0.000 virginica ( 0.00000 0.00000 1.00000 ) *
> tr$frame
var n dev yval splits.cutleft splits.cutright yprob.setosa yprob.versicolor yprob.virginica
1 Petal.Length 150 329.583687 setosa <2.45 >2.45 0.33333333 0.33333333 0.33333333
2 <leaf> 50 0.000000 setosa 1.00000000 0.00000000 0.00000000
3 Petal.Width 100 138.629436 versicolor <1.75 >1.75 0.00000000 0.50000000 0.50000000
6 Petal.Length 54 33.317509 versicolor <4.95 >4.95 0.00000000 0.90740741 0.09259259
12 Sepal.Length 48 9.721422 versicolor <5.15 >5.15 0.00000000 0.97916667 0.02083333
24 <leaf> 5 5.004024 versicolor 0.00000000 0.80000000 0.20000000
25 <leaf> 43 0.000000 versicolor 0.00000000 1.00000000 0.00000000
13 <leaf> 6 7.638170 virginica 0.00000000 0.33333333 0.66666667
7 Petal.Length 46 9.635384 virginica <4.95 >4.95 0.00000000 0.02173913 0.97826087
14 <leaf> 6 5.406735 virginica 0.00000000 0.16666667 0.83333333
15 <leaf> 40 0.000000 virginica 0.00000000 0.00000000 1.00000000
Entonces, hay métodos para la impresión y el trazado de los objetos. Las principales funciones son un genérico tree:::plot.tree
(método puse un triple :
que le permite ver el código en R directamente) confiar en tree:::treepl
(pantalla gráfica) y tree:::treeco
(nodos de cálculo de coordenadas). Estas funciones de esperar que el obj$frame
de la representación del árbol. Otras sutiles cuestiones: (1) el argumento de type = c("proportional", "uniform")
en el valor predeterminado de trazado método, tree:::plot.tree
, ayuda a administrar la distancia vertical entre los nodos (proportional
significa que es proporcional a la desviación, uniform
significa que es fija); (2) que necesita para complementar plot(tr)
a través de una llamada a text(tr)
agregar etiquetas de texto de los nodos y divisiones, que en este caso significa que usted también tendrá que echar un vistazo a tree:::text.tree
.
El getTree
método de randomForest
devuelve una estructura diferente, que está documentada en la ayuda en línea. Una salida típica se muestra a continuación, con los nodos terminales indicados por status
código (-1). (De nuevo, la salida será diferente en función del tipo de tarea, pero sólo en la status
y prediction
columnas).
> library(randomForest)
> rf <- randomForest(Species ~ ., data=iris)
> getTree(rf, 1, labelVar=TRUE)
left daughter right daughter split var split point status prediction
1 2 3 Petal.Length 4.75 1 <NA>
2 4 5 Sepal.Length 5.45 1 <NA>
3 6 7 Sepal.Width 3.15 1 <NA>
4 8 9 Petal.Width 0.80 1 <NA>
5 10 11 Sepal.Width 3.60 1 <NA>
6 0 0 <NA> 0.00 -1 virginica
7 12 13 Petal.Width 1.90 1 <NA>
8 0 0 <NA> 0.00 -1 setosa
9 14 15 Petal.Width 1.55 1 <NA>
10 0 0 <NA> 0.00 -1 versicolor
11 0 0 <NA> 0.00 -1 setosa
12 16 17 Petal.Length 5.40 1 <NA>
13 0 0 <NA> 0.00 -1 virginica
14 0 0 <NA> 0.00 -1 versicolor
15 0 0 <NA> 0.00 -1 virginica
16 0 0 <NA> 0.00 -1 versicolor
17 0 0 <NA> 0.00 -1 virginica
Si usted puede manejar para convertir la tabla de arriba a la generada por tree
, usted probablemente será capaz de personalizar tree:::treepl
, tree:::treeco
y tree:::text.tree
para satisfacer sus necesidades, a pesar de que no tengo un ejemplo de este enfoque. En particular, es probable que desee deshacerse de el uso de la desviación, la clase de probabilidades, etc. que no son significativos en RF. Todo lo que quieres es configurar los nodos de coordenadas y dividir los valores. Usted podría utilizar fixInNamespace()
por que, pero, para ser honesto, no estoy seguro de que este es el camino correcto a seguir.
Tercera (y ciertamente inteligente) solución: Escribir un cierto as.tree
helper
la función que alivia todos los de arriba "parches". Usted podría utilizar R métodos de trazado o, probablemente mejor, Klimt (directamente desde R) para mostrar los árboles individuales.