Pruebas de reglas generadas por el paquete Rpart.
Quiero probar de forma programática una regla generada a partir de un árbol. En los árboles, la ruta entre la raíz y una hoja (nodo terminal) podría interpretarse como una regla.
En R, podríamos usar elrpart
paquete y haga lo siguiente: (En este post, usaré eliris
conjunto de datos, sólo para fines de ejemplo)
library(rpart)
model <- rpart(Species ~ ., data=iris)
Con estas dos líneas conseguí un árbol llamadomodel
cuya clase esrpart.object
(rpart
documentación, página 21). Este objeto tiene mucha información y admite una variedad de métodos. En particular, el objeto tiene unaframe
Variable (a la que se puede acceder de forma estándar:model$frame
) (ídem) y el métodopath.rpath
(rpart
documentación, página 7), que le proporciona la ruta desde el nodo raíz al nodo de interés (node
argumento en la función)
losrow.names
delframe
La variable contiene los números de nodo del árbol. losvar
columna da la variable de división en el nodo,yval
el valor ajustado yyval2
Probabilidades de clase y otra información.
> model$frame
var n wt dev yval complexity ncompete nsurrogate yval2.1 yval2.2 yval2.3 yval2.4 yval2.5 yval2.6 yval2.7
1 Petal.Length 150 150 100 1 0.50 3 3 1.00000000 50.00000000 50.00000000 50.00000000 0.33333333 0.33333333 0.33333333
2 <leaf> 50 50 0 1 0.01 0 0 1.00000000 50.00000000 0.00000000 0.00000000 1.00000000 0.00000000 0.00000000
3 Petal.Width 100 100 50 2 0.44 3 3 2.00000000 0.00000000 50.00000000 50.00000000 0.00000000 0.50000000 0.50000000
6 <leaf> 54 54 5 2 0.00 0 0 2.00000000 0.00000000 49.00000000 5.00000000 0.00000000 0.90740741 0.09259259
7 <leaf> 46 46 1 3 0.01 0 0 3.00000000 0.00000000 1.00000000 45.00000000 0.00000000 0.02173913 0.97826087
Pero solo lo marcado como<leaf>
en elvar
columna son nodos terminales (hojas). En este caso los nodos son 2, 6 y 7.
Como se mencionó anteriormente, puede utilizar elpath.rpart
Método para extraer una regla (esta técnica se utiliza en elrattle
paquete y en el articuloPuntaje de crédito de Sharma, como sigue:
Adicionalmente, el modelo mantiene los valores del valor predicho en
predicted.levels <- attr(model, "ylevels")
Este valor corresponde a la columna.yval
en elmodel$frame
conjunto de datos.
Para la hoja con el número de nodo 7 (número de fila 5), el valor predicho es
> ylevels[model$frame[5, ]$yval]
[1] "virginica"
y la regla es
> rule <- path.rpart(model, nodes = 7)
node number: 7
root
Petal.Length>=2.45
Petal.Width>=1.75
Entonces, la regla podría ser leída como
If Petal.Length >= 2.45 AND Petal.Width >= 1.75 THEN Species = Virginica
Sé que puedo probar (en un conjunto de datos de prueba, usaré el conjunto de datos del iris nuevamente) cuántos positivos verdaderos tengo para esta regla, subconjunto del nuevo conjunto de datos de la siguiente manera
> hits <- subset(iris, Petal.Length >= 2.45 & Petal.Width >= 1.75)
y luego calculando la matriz de confusión
> table(hits$Species, hits$Species == "virginica")
FALSE TRUE
setosa 0 0
versicolor 1 0
virginica 0 45
(Nota: usé el mismo conjunto de datos del iris que las pruebas)
¿Cómo podría evaluar la regla de manera programática? Podría extraer las condiciones de la regla de la siguiente manera
> unlist(rule, use.names = FALSE)[-1]
[1] "Petal.Length>=2.45" "Petal.Width>=1.75"
Pero, ¿cómo puedo continuar desde aquí? No puedo usar elsubset
función
Gracias por adelantado
NOTA: Esta pregunta ha sido fuertemente editada para mayor claridad.