2017-01-31 1 views
1

Salut J'essaie actuellement d'extraire certaines des informations de nœud interne stockées dans l'objet de fête constant dans R en utilisant ctree dans partykit, mais je trouve que la navigation dans les objets peu difficile, je suis capable d'afficher les informations sur un complot mais je ne suis pas sûr de savoir comment extraire l'information - je pense qu'il faut nodeapply ou une autre fonction dans le partykit?R Extraction des informations de nœuds internes et divisions de ctree (partykit)

library(partykit) 
irisct <- ctree(Species ~ .,data = iris) 
plot(irisct, inner_panel = node_barplot(irisct)) 

Plot with inner node details

Toutes les informations sont accessibles par les fonctions de terrain, mais je suis après une sortie de texte similaire à: Example output

Répondre

2

L'astuce principale (comme précédemment pointé par @ G5W) est de prendre le sous-ensemble [id] de l'objet party puis d'extraire les données (par $data ou en utilisant la fonction data_party()) qui contient la réponse. Je recommanderais d'abord de construire une table avec des fréquences absolues, puis d'en calculer les fréquences relatives et marginales. Utilisation de l'objet irisct la table ordinaire peut être obtenue par

tab <- sapply(1:length(irisct), function(id) { 
    y <- data_party(irisct[id]) 
    y <- y[["(response)"]] 
    table(y) 
}) 
tab 
##   [,1] [,2] [,3] [,4] [,5] [,6] [,7] 
## setosa  50 50 0 0 0 0 0 
## versicolor 50 0 50 49 45 4 1 
## virginica 50 0 50 5 1 4 45 

Ensuite, nous pouvons ajouter un peu de mise en forme à un bel objet table:

colnames(tab) <- 1:length(irisct) 
tab <- as.table(tab) 
names(dimnames(tab)) <- c("Species", "Node") 

Et puis utilisez prop.table() et margin.table() pour calculer les fréquences nous sommes intéressés par.La méthode as.data.frame() de transformation de la mise en page table à un « long » data.frame:

as.data.frame(prop.table(tab, 1)) 
##  Species Node  Freq 
## 1  setosa 1 0.500000000 
## 2 versicolor 1 0.251256281 
## 3 virginica 1 0.322580645 
## 4  setosa 2 0.500000000 
## 5 versicolor 2 0.000000000 
## 6 virginica 2 0.000000000 
## 7  setosa 3 0.000000000 
## 8 versicolor 3 0.251256281 
## 9 virginica 3 0.322580645 
## 10  setosa 4 0.000000000 
## 11 versicolor 4 0.246231156 
## 12 virginica 4 0.032258065 
## 13  setosa 5 0.000000000 
## 14 versicolor 5 0.226130653 
## 15 virginica 5 0.006451613 
## 16  setosa 6 0.000000000 
## 17 versicolor 6 0.020100503 
## 18 virginica 6 0.025806452 
## 19  setosa 7 0.000000000 
## 20 versicolor 7 0.005025126 
## 21 virginica 7 0.290322581 

as.data.frame(margin.table(tab, 2)) 
## Node Freq 
## 1 1 150 
## 2 2 50 
## 3 3 100 
## 4 4 54 
## 5 5 46 
## 6 6 8 
## 7 7 46 

Et les informations scission peut être obtenue avec le (encore désexporter) fonction .list.rules.party(). Vous avez juste besoin de demander tous les ID de nœud (la valeur par défaut est d'utiliser uniquement les ID de nœud terminal):

partykit:::.list.rules.party(irisct, i = nodeids(irisct)) 
##                1 
##                "" 
##                2 
##           "Petal.Length <= 1.9" 
##                3 
##           "Petal.Length > 1.9" 
##                4 
##      "Petal.Length > 1.9 & Petal.Width <= 1.7" 
##                5 
## "Petal.Length > 1.9 & Petal.Width <= 1.7 & Petal.Length <= 4.8" 
##                6 
## "Petal.Length > 1.9 & Petal.Width <= 1.7 & Petal.Length > 4.8" 
##                7 
##      "Petal.Length > 1.9 & Petal.Width > 1.7" 
+0

Merci beaucoup Achim! Je me demandais comment obtenir tous les nœuds listés avec list.rules, je vais vérifier la fonction data_party aussi car je pense que ça sera utile aussi. –

1

La plupart des informations que vous voulez est accessible sans beaucoup de travail. Je vais montrer comment obtenir l'information, mais laissez-vous formater les informations dans une jolie table. Notez que votre structure arborescente irisct est juste une liste de chacun des nœuds.

length(irisct) 
[1] 7 

Chaque nœud a un champ data qui contient les points qui ont fait descendre loin dans l'arbre, de sorte que vous pouvez obtenir le nombre d'observations au niveau du noeud en comptant les lignes.

dim(irisct[4]$data) 
[1] 54 5 
nrow(irisct[4]$data) 
[1] 54 

Ou les faire à la fois pour obtenir votre table 2

NObs = sapply(1:7, function(n) { nrow(irisct[n]$data) }) 
NObs 
[1] 150 50 100 54 46 8 46 

La première colonne des données à un noeud est la classe (espèces), afin que vous puissiez obtenir le nombre de chaque classe et la probabilité de chaque classe à un noeud

table(irisct[4]$data[1]) 
setosa versicolor virginica 
    0   49   5 
table(irisct[4]$data[1])/NObs[4] 
setosa versicolor virginica 
0.00000000 0.90740741 0.09259259 

les informations scission dans la table 3 est un peu plus délicate. Pourtant, vous pouvez obtenir une version texte de ce que vous avez juste besoin en imprimant le nœud de niveau supérieur

irisct[1] 
Model formula: 
Species ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width 
Fitted party: 
[1] root 
| [2] Petal.Length <= 1.9: setosa (n = 50, err = 0.0%) 
| [3] Petal.Length > 1.9 
| | [4] Petal.Width <= 1.7 
| | | [5] Petal.Length <= 4.8: versicolor (n = 46, err = 2.2%) 
| | | [6] Petal.Length > 4.8: versicolor (n = 8, err = 50.0%) 
| | [7] Petal.Width > 1.7: virginica (n = 46, err = 2.2%) 
Number of inner nodes: 3 
Number of terminal nodes: 4 

Pour enregistrer la sortie pour l'analyse et l'affichage

TreeSplits = capture.output(print(irisct[1])) 
+0

merci Impressionnant! comment référencer un nœud dans l'arbre avec $ data semble être beaucoup de ce que je cherche –