Quelle est la meilleure façon de présenter une forêt au hasard dans une publication?

75

J'utilise l'algorithme de forêt aléatoire en tant que classificateur robuste de deux groupes dans une étude de microréseau comportant des milliers d'éléments.

  • Quelle est la meilleure façon de présenter la forêt aléatoire de manière à ce qu'il y ait suffisamment d'informations pour la rendre reproductible dans un document?
  • Existe-t-il une méthode de tracé dans R pour tracer réellement l'arbre, s'il y a un petit nombre d'entités?
  • Est-ce que l'estimation du taux d'erreur hors bande est la meilleure statistique à citer?
danielsbrewer
la source
2
Il n'y a pas un seul arbre ... Mais voyez la réponse de @ Shane pour en avoir tracé l'un à des fins d'illustration.
chl
Il est certainement intéressant d'envisager randomForest :: partialPlot, stats.stackexchange.com/questions/92150/…
Soren Havelund Welling le
1
vous pouvez essayer mon logiciel de visualisation aléatoire de la forêt, forestFloor - forestfloor.dk
Soren Havelund Welling

Réponses:

48

Pour ce qui est de le rendre reproductible, le meilleur moyen est de fournir une recherche reproductible (code et données) avec le papier. Rendez-le disponible sur votre site Web ou sur un site d'hébergement (comme github).

En ce qui concerne la visualisation, Leo Breiman a fait un travail intéressant à ce sujet (voir sa page d’accueil , en particulier la section sur les graphiques ).

Mais si vous utilisez R, le randomForestpaquet a quelques fonctions utiles:

data(mtcars)
mtcars.rf <- randomForest(mpg ~ ., data=mtcars, ntree=1000, keep.forest=FALSE,
                           importance=TRUE)
plot(mtcars.rf, log="y")
varImpPlot(mtcars.rf)

Et

set.seed(1)
data(iris)
iris.rf <- randomForest(Species ~ ., iris, proximity=TRUE,
                        keep.forest=FALSE)
MDSplot(iris.rf, iris$Species)

Je ne suis pas au courant d'un moyen simple de tracer un arbre, mais vous pouvez utiliser la getTreefonction pour récupérer l'arbre et le tracer séparément.

getTree(randomForest(iris[,-5], iris[,5], ntree=10), 3, labelVar=TRUE)

La présentation de Strobl / Zeileis sur "Pourquoi et comment utiliser des mesures aléatoires d'importance variable de la forêt (et comment vous ne devriez pas le faire)" contient des exemples d'arbres qui doivent avoir été produits de cette manière. Ce billet de blog sur les modèles d’arbre contient quelques exemples intéressants de diagrammes CART que vous pouvez utiliser, par exemple.

Comme @chl a commenté, un seul arbre n'a pas vraiment de sens dans ce contexte. Aussi, à moins de l'utiliser pour expliquer ce qu'est une forêt aléatoire, je ne l'inclurais pas dans un document.

Shane
la source
4
Petite extension sur les tracés: plot.randomForestmontre comment l’erreur OOB et l’erreur OOB en classe ont évolué avec le nombre croissant d’arbres; varImpPlotaffiche les mesures d'importance d'attribut pour les attributs supérieurs et MDSplottous les objets tracés sur la projection 2D de la mesure de proximité d'un objet RF.
+1 pour citer la MDSplot()fonction. Je dois admettre que j'utilise souvent les RF comme moyen de mettre en évidence des grappes d'individus (en fonction de la mesure de proximité RF) plutôt que de sélectionner les meilleures caractéristiques. Les cliniciens lisent souvent beaucoup plus facilement de tels graphiques que les graphiques à points de var. importance ...
chl
18
  1. Comme Shane l'a écrit: faites-en une recherche reproductible + incluez des graines aléatoires, parce que RF est stochastique.
  2. Tout d'abord, tracer des arbres simples formant RF est un non-sens; c'est un classificateur d'ensemble, cela n'a de sens que dans son ensemble. Mais même tracer toute la forêt n’a aucun sens: c’est un classificateur à boîte noire; il n’est donc pas destiné à expliquer les données avec leur structure, mais à reproduire le processus original. Faites plutôt quelques complots suggérés par Shane.
  3. En pratique, OOB est une très bonne approximation d'erreur. Cependant, ce fait n’est pas un fait largement accepté. Il est donc préférable de faire un CV pour le publier.

la source
Ainsi, @mbq lors de la rédaction d'un CV est-il valide pour commencer par créer une forêt aléatoire avec tous les échantillons sélectionnés; le faire deux fois une fois avec tous et deuxièmement avec les 10 premières variables (qui peuvent être citées dans un article). Ensuite, effectuez une validation croisée «laissez-passer» (en sélectionnant les 10 meilleurs gènes à chaque essai) et citez l’erreur CV qui en découle?
danielsbrewer
1
@danielsbrewer Je le ferais d'une autre manière (en accordant plus d'attention à la sélection des fonctionnalités), mais c'est correct; Cependant, il est plus question d'analyser la sélection des fonctionnalités RF que de sélectionner les meilleurs marqueurs pour votre problème biologique.
2
Le problème principal est qu’il est très difficile de comparer deux modèles (modèle = méthode d’apprentissage + méthode de sélection des fonctionnalités), mais pour simplifier, vous pouvez supposer quelque chose (comme je vais utiliser RF et sélectionner les 10 meilleurs attributs) et admettre que vous savez. que cela peut être sous-optimal, mais vous en convenez alors que vous êtes par exemple satisfait de la précision. Dans ce cas, votre seul problème est de supprimer le biais de sélection d'attribut. à confirmer
2
Je ferais donc un sac simple: vous créez 10 (ou 30 si vous avez un bon ordinateur) des sous-échantillons aléatoires d’objets (disons par tirage au sort avec remplacement), entraînez RF sur chacun, obtenez son importance et restituez un classement de chacun. attribut moyenné sur toutes les répétitions (le meilleur attribut obtient le rang 1, le deuxième 2 et ainsi de suite; il peut donc être moyenné de manière à attribuer l'attribut qui était 12 fois le premier et 18 fois le second ont un rang de 1,6), enfin sélectionnez 10 avec les meilleurs rangs et appelez-les vos marqueurs. Utilisez ensuite un CV (LOO, échantillonnage aléatoire 10 fois ou de préférence) pour obtenir une approximation d'erreur de RF en utilisant vos marqueurs. à confirmer
2
Signalez les rangs (espérons-le, ils devraient être assez proches de 1,2,3 ...), erreur CV avec son écart (comptez simplement l'écart type des résultats de chaque tour CV) et erreur OOB (sera probablement identique à erreur CV). AVERTISSEMENT: Ce n'est pas une méthode pour sélectionner le nombre optimal d'attributs - vous avez besoin de RFE et de CV imbriqués pour le faire. DISCLAIMER2: Je n'ai pas travaillé avec de telles données, donc je ne garantis pas que vos arbitres en seront satisfaits (bien que je pense qu'ils le devraient).
13

Gardez à l'esprit les mises en garde dans les autres réponses sur le fait que l'intrigue a nécessairement un sens. Mais si vous voulez une parcelle à des fins d'illustration / pédagogique, l'extrait suivant de R peut être utile. Pas difficile d'ajouter "point de partage" au texte de bord si vous en avez besoin.

to.dendrogram <- function(dfrep,rownum=1,height.increment=0.1){

  if(dfrep[rownum,'status'] == -1){
    rval <- list()

    attr(rval,"members") <- 1
    attr(rval,"height") <- 0.0
    attr(rval,"label") <- dfrep[rownum,'prediction']
    attr(rval,"leaf") <- TRUE

  }else{##note the change "to.dendrogram" and not "to.dendogram"
    left <- to.dendrogram(dfrep,dfrep[rownum,'left daughter'],height.increment)
    right <- to.dendrogram(dfrep,dfrep[rownum,'right daughter'],height.increment)
    rval <- list(left,right)

    attr(rval,"members") <- attr(left,"members") + attr(right,"members")
    attr(rval,"height") <- max(attr(left,"height"),attr(right,"height")) + height.increment
    attr(rval,"leaf") <- FALSE
    attr(rval,"edgetext") <- dfrep[rownum,'split var']
    #To add Split Point in Dendrogram
    #attr(rval,"edgetext") <- paste(dfrep[rownum,'split var'],"\n<",round(dfrep[rownum,'split point'], digits = 2),"=>", sep = " ")
  }

  class(rval) <- "dendrogram"

  return(rval)
}

mod <- randomForest(Species ~ .,data=iris)
tree <- getTree(mod,1,labelVar=TRUE)

d <- to.dendrogram(tree)
str(d)
plot(d,center=TRUE,leaflab='none',edgePar=list(t.cex=1,p.col=NA,p.lty=0))
Patrick Caldon
la source
1
Le code produit une très bonne parcelle d'arbres. Mais les valeurs ne sont pas affichées. Une fonction text () doit probablement être ajoutée après la dernière instruction (plot).
rnso