Les prévisions d'un modèle de forêt aléatoire ont-elles un intervalle de prévision?

52

Si je lance un randomForestmodèle, je peux alors faire des prédictions basées sur ce modèle. Existe-t-il un moyen d’obtenir un intervalle de prévision de chacune des prévisions de sorte que je sache à quel point le modèle est sûr de sa réponse. Si cela est possible, est-il simplement basé sur la variabilité de la variable dépendante pour l'ensemble du modèle ou aura-t-il des intervalles plus larges et plus étroits en fonction de l'arbre de décision particulier suivi pour une prédiction particulière?

Dean MacGregor
la source
3
Autant que je sache, toutes les bibliothèques RF ont une sorte de scorefonction permettant d’évaluer les performances. Étant donné que le résultat est basé sur le vote majoritaire des arbres de la forêt, en cas de classification, il vous donnera une probabilité que ce résultat soit vrai, sur la base de la distribution des votes. Je ne suis toutefois pas sûr de la régression ... Quelle bibliothèque utilisez-vous?
Sashkello
1
Vous devriez lire ceci: stats.stackexchange.com/questions/12425/…
0asa

Réponses:

40

Ceci est en partie une réponse à @Sashikanth Dareddy (car cela ne rentrera pas dans un commentaire) et en partie à une réponse au message original.

Rappelez-vous ce qu'est un intervalle de prédiction, c'est un intervalle ou un ensemble de valeurs où nous prédisons que les observations futures se trouveront. Généralement, l’intervalle de prédiction comprend 2 éléments principaux qui déterminent sa largeur, l’un représentant l’incertitude concernant la moyenne prédite (ou tout autre paramètre), l’intervalle de confiance, et l’autre représentant la variabilité des observations individuelles autour de cette moyenne. L’intervalle de confiance est assez robuste du fait du théorème de la limite centrale et, dans le cas d’une forêt aléatoire, l’amorçage aide également. Mais l'intervalle de prédiction dépend entièrement des hypothèses sur la répartition des données en fonction des variables de prédicteur. Le CLT et l'amorçage n'ont aucun effet sur cette partie.

L'intervalle de prédiction doit être plus large, l'intervalle de confiance correspondant étant également plus large. Les hypothèses sur une variance égale ou non qui affectent la largeur de l'intervalle de prévision sont également liées à la connaissance du chercheur, et non au modèle de forêt aléatoire.

Un intervalle de prédiction n'a pas de sens pour un résultat catégorique (vous pouvez faire un ensemble de prédiction plutôt qu'un intervalle, mais la plupart du temps, ce ne serait probablement pas très informatif).

Nous pouvons voir certains des problèmes liés aux intervalles de prédiction en simulant des données pour lesquelles nous connaissons la vérité exacte. Considérez les données suivantes:

set.seed(1)

x1 <- rep(0:1, each=500)
x2 <- rep(0:1, each=250, length=1000)

y <- 10 + 5*x1 + 10*x2 - 3*x1*x2 + rnorm(1000)

Ces données particulières suivent les hypothèses pour une régression linéaire et sont assez simples pour un ajustement aléatoire de forêt. Nous savons d'après le modèle "vrai" que, lorsque les deux prédicteurs valent 0, que la moyenne est égale à 10, nous savons également que les points individuels suivent une distribution normale avec un écart-type de 1. Cela signifie que l'intervalle de prédiction de 95% basé sur une connaissance parfaite pour ces points seraient de 8 à 12 (bien en fait de 8,04 à 11,96, mais l’arrondi le rend plus simple). Tout intervalle de prédiction estimé doit être plus large que prévu (ne pas disposer d'informations parfaites ajoute de la largeur à compenser) et inclure cette plage.

Regardons les intervalles de régression:

fit1 <- lm(y ~ x1 * x2)

newdat <- expand.grid(x1=0:1, x2=0:1)

(pred.lm.ci <- predict(fit1, newdat, interval='confidence'))
#        fit       lwr      upr
# 1 10.02217  9.893664 10.15067
# 2 14.90927 14.780765 15.03778
# 3 20.02312 19.894613 20.15162
# 4 21.99885 21.870343 22.12735

(pred.lm.pi <- predict(fit1, newdat, interval='prediction'))
#        fit      lwr      upr
# 1 10.02217  7.98626 12.05808
# 2 14.90927 12.87336 16.94518
# 3 20.02312 17.98721 22.05903
# 4 21.99885 19.96294 24.03476

Nous pouvons constater qu'il existe une certaine incertitude dans les moyennes estimées (intervalle de confiance), ce qui nous donne un intervalle de prédiction plus large (mais comprenant) la plage de 8 à 12.

Examinons maintenant l'intervalle basé sur les prévisions individuelles d'arbres individuels (nous devrions nous attendre à ce qu'elles soient plus larges, car la forêt aléatoire ne bénéficie pas des hypothèses (que nous savons être vraies pour ces données) comme le fait la régression linéaire):

library(randomForest)
fit2 <- randomForest(y ~ x1 + x2, ntree=1001)

pred.rf <- predict(fit2, newdat, predict.all=TRUE)

pred.rf.int <- apply(pred.rf$individual, 1, function(x) {
  c(mean(x) + c(-1, 1) * sd(x), 
  quantile(x, c(0.025, 0.975)))
})

t(pred.rf.int)
#                           2.5%    97.5%
# 1  9.785533 13.88629  9.920507 15.28662
# 2 13.017484 17.22297 12.330821 18.65796
# 3 16.764298 21.40525 14.749296 21.09071
# 4 19.494116 22.33632 18.245580 22.09904

Les intervalles sont plus larges que les intervalles de prédiction de régression, mais ils ne couvrent pas toute la plage. Ils incluent les vraies valeurs et peuvent donc être légitimes en tant qu'intervalles de confiance, mais ils ne font que prédire où se trouve la moyenne (valeur prédite) sans l'élément supplémentaire pour la distribution autour de cette moyenne. Pour le premier cas où x1 et x2 sont tous deux égaux à 0, les intervalles ne descendent pas au-dessous de 9,7, ce qui est très différent de l'intervalle de prédiction véritable qui descend à 8. Si nous générons de nouveaux points de données, il y aura plusieurs points (beaucoup plus moins de 5%) qui se trouvent dans les intervalles vrais et de régression, mais ne tombent pas dans les intervalles aléatoires de forêt.

Pour générer un intervalle de prédiction, vous devez émettre de fortes hypothèses sur la répartition des points individuels autour des moyennes prédites. Vous pouvez ensuite prendre les prédictions des arbres individuels (l’intervalle de confiance initialisé), puis générer une valeur aléatoire à partir de la valeur supposée. distribution avec ce centre. Les quantiles de ces pièces générées peuvent constituer l'intervalle de prédiction (mais je le testerais quand même, vous devrez peut-être répéter le processus plusieurs fois et combiner).

Voici un exemple de cela en ajoutant des écarts normaux (puisque nous savons que les données d'origine utilisaient un comportement normal) aux prévisions avec l'écart type basé sur la MSE estimée à partir de cet arbre:

pred.rf.int2 <- sapply(1:4, function(i) {
  tmp <- pred.rf$individual[i, ] + rnorm(1001, 0, sqrt(fit2$mse))
  quantile(tmp, c(0.025, 0.975))
})
t(pred.rf.int2)
#           2.5%    97.5%
# [1,]  7.351609 17.31065
# [2,] 10.386273 20.23700
# [3,] 13.004428 23.55154
# [4,] 16.344504 24.35970

Ces intervalles contiennent ceux qui sont basés sur une connaissance parfaite. Mais ils dépendront grandement des hypothèses retenues (les hypothèses sont valables ici car nous avons utilisé la connaissance de la manière dont les données ont été simulées, elles risquent de ne pas être aussi valables dans les cas réels). Je voudrais encore répéter les simulations plusieurs fois pour des données qui ressemblent davantage à vos données réelles (mais simulées afin que vous sachiez la vérité) plusieurs fois avant de faire pleinement confiance à cette méthode.

Greg Snow
la source
11

Je me rends compte que c’est un vieux billet, mais j’ai fait quelques simulations à ce sujet et je pense partager mes conclusions.

@GregSnow a publié un article très détaillé à ce sujet, mais je pense que lorsqu'il calculait l'intervalle à l'aide de prédictions d'arbres individuels, il examinait qui ne représente qu'un intervalle de prédiction de 70%. Nous devons examiner pour obtenir l'intervalle de prédiction de 95%.[ μ + 1,96 * σ , μ - 1,96 * σ ][μ+σ,μσ][μ+1.96σ,μ1.96σ]

En apportant cette modification au code @GregSnow, nous obtenons les résultats suivants

set.seed(1)
x1 <- rep( 0:1, each=500 )
x2 <- rep( 0:1, each=250, length=1000 )
y <- 10 + 5*x1 + 10*x2 - 3*x1*x2 + rnorm(1000)

library(randomForest)
fit2 <- randomForest(y~x1+x2)
pred.rf <- predict(fit2, newdat, predict.all=TRUE)
pred.rf.int <- t(apply( pred.rf$individual, 1, function(x){ 
  c( mean(x) + c(-1.96,1.96)*sd(x), quantile(x, c(0.025,0.975)) )}))

pred.rf.int
                          2.5%    97.5%
1  7.826896 16.05521  9.915482 15.31431
2 11.010662 19.35793 12.298995 18.64296
3 14.296697 23.61657 14.749248 21.11239
4 18.000229 23.73539 18.237448 22.10331

Maintenant, en comparant ces intervalles avec les intervalles générés en ajoutant un écart normal aux prédictions avec un écart type, comme MSE comme @GregSnow l’a suggéré,

pred.rf.int2 <- sapply(1:4, function(i) {
   tmp <- pred.rf$individual[i,] + rnorm(1000, 0, sqrt(fit2$mse))
   quantile(tmp, c(0.025, 0.975))
   })
t(pred.rf.int2)
          2.5%    97.5%
[1,]  7.486895 17.21144
[2,] 10.551811 20.50633
[3,] 12.959318 23.46027
[4,] 16.444967 24.57601

L'intervalle entre ces deux approches semble maintenant très proche. Le tracé de l'intervalle de prédiction pour les trois approches par rapport à la distribution d'erreur dans ce cas est présenté ci-dessous.

entrez la description de l'image ici

  • Lignes noires = intervalles de prédiction de la régression linéaire,
  • Lignes rouges = intervalles de forêt aléatoires calculés sur des prévisions individuelles,
  • Lignes bleues = intervalles de forêt aléatoires calculés en ajoutant un écart normal aux prévisions

Maintenant, relançons la simulation, mais cette fois en augmentant la variance du terme d'erreur. Si nos calculs d’intervalle de prédiction sont bons, nous devrions nous retrouver avec des intervalles plus larges que ce que nous avons obtenu plus haut.

set.seed(1)
x1 <- rep( 0:1, each=500 )
x2 <- rep( 0:1, each=250, length=1000 )
y <- 10 + 5*x1 + 10*x2 - 3*x1*x2 + rnorm(1000,mean=0,sd=5)

fit1 <- lm(y~x1+x2)
newdat <- expand.grid(x1=0:1,x2=0:1)
predict(fit1,newdata=newdat,interval = "prediction")
      fit       lwr      upr
1 10.75006  0.503170 20.99695
2 13.90714  3.660248 24.15403
3 19.47638  9.229490 29.72327
4 22.63346 12.386568 32.88035

set.seed(1)
fit2 <- randomForest(y~x1+x2,localImp=T)
pred.rf.int <- t(apply( pred.rf$individual, 1, function(x){ 
  c( mean(x) + c(-1.96,1.96)*sd(x), quantile(x, c(0.025,0.975)) )}))
pred.rf.int
                          2.5%    97.5%
1  7.889934 15.53642  9.564565 15.47893
2 10.616744 18.78837 11.965325 18.51922
3 15.024598 23.67563 14.724964 21.43195
4 17.967246 23.88760 17.858866 22.54337

pred.rf.int2 <- sapply(1:4, function(i) {
   tmp <- pred.rf$individual[i,] + rnorm(1000, 0, sqrt(fit2$mse))
   quantile(tmp, c(0.025, 0.975))
   })
t(pred.rf.int2)
         2.5%    97.5%
[1,] 1.291450 22.89231
[2,] 4.193414 25.93963
[3,] 7.428309 30.07291
[4,] 9.938158 31.63777

entrez la description de l'image ici

Cela montre clairement que le calcul des intervalles de prédiction par la deuxième approche est beaucoup plus précis et donne des résultats assez proches de l'intervalle de prédiction de la régression linéaire.

En prenant l'hypothèse de la normalité, il existe un autre moyen plus facile de calculer les intervalles de prédiction à partir d'une forêt aléatoire. Nous avons la valeur prédite ( ) et l'erreur quadratique moyenne ( ) de . Donc, la prédiction de chaque arbre individuel peut être considérée comme . En utilisant les propriétés de distribution normales, notre prédiction à partir de la forêt aléatoire aurait la distribution . En appliquant ceci à l'exemple que nous avons discuté ci-dessus, nous obtenons les résultats ci-dessous M S E i N ( μ i , R M S E i ) N ( Σ μ i / n , Σ R M S E i / n )μiMSEiN(μi,RMSEi)N(μi/n,RMSEi/n)

mean.rf <- pred.rf$aggregate
sd.rf <- mean(sqrt(fit2$mse))
pred.rf.int3 <- cbind(mean.rf - 1.96*sd.rf, mean.rf + 1.96*sd.rf)
pred.rf.int3
1  1.332711 22.09364
2  4.322090 25.08302
3  8.969650 29.73058
4 10.546957 31.30789

Celles-ci correspondent très bien aux intervalles du modèle linéaire et à l'approche suggérée par @GregSnow. Mais notez que l’hypothèse sous-jacente dans toutes les méthodes que nous avons discutées est que les erreurs suivent une distribution normale.

ab90hi
la source
10

Si vous utilisez R, vous pouvez facilement produire des intervalles de prédiction pour les prédictions d’une régression aléatoire de forêts: il suffit d’utiliser le paquet quantregForest(disponible au CRAN ) et de lire le document de N. Meinshausen sur la manière dont on peut inférer des quantiles conditionnels avec des forêts de régression de quantiles et comment. peut être utilisé pour construire des intervalles de prédiction. Très instructif même si vous ne travaillez pas avec R!

utilisateur7417
la source
Il semble que le papier ait été déplacé ici: jmlr.org/papers/volume7/meinshausen06a/meinshausen06a.pdf
Monica le
2
Cela semble être la réponse appropriée et n'exige pas d'hypothèses de répartition concernant l'intervalle de prévision. Il y a un tutoriel sur comment faire cela en python ici: blog.datadive.net/prediction-intervals-for-random-forests
colin
6

C'est facile à résoudre avec randomForest.

Permettez-moi d'abord de traiter de la tâche de régression (en supposant que votre forêt compte 1 000 arbres). Dans la predictfonction, vous avez la possibilité de renvoyer les résultats des arbres individuels. Cela signifie que vous recevrez une sortie de 1000 colonnes. Nous pouvons prendre la moyenne des 1000 colonnes pour chaque ligne - il s’agit de la sortie normale que RF aurait produite de toute façon. Maintenant, pour obtenir l’intervalle de prédiction, disons +/- 2 std. les écarts, tout ce que vous devez faire est, pour chaque ligne, à partir des 1000 valeurs, calculer +/- 2 std. déviations et faites-en vos limites supérieure et inférieure sur votre prédiction.

Deuxièmement, dans le cas de la classification, rappelez-vous que chaque arbre génère 1 ou 0 (par défaut) et que la somme sur les 1 000 arbres divisés par 1 000 donne la probabilité de classe (dans le cas de la classification binaire). Pour définir un intervalle de prédiction sur la probabilité, vous devez modifier la valeur min. nodesize option (voir la documentation randomForest pour le nom exact de cette option) une fois que vous lui attribuez la valeur >> 1, les arbres individuels produiront des nombres compris entre 1 et 0. À partir de là, vous pouvez répéter le processus décrit ci-dessus pour la tâche de régression.

J'espère que cela à du sens.


la source
Je ne l'ai pas essayé mais cela semble logique. Merci d'avoir répondu à ma vieille question.
Dean MacGregor
1
Je pense que cette méthode donnerait quelque chose de plus proche d'un intervalle de confiance qu'un intervalle de prédiction. Les résultats doivent être comparés à un modèle linéaire où la théorie des intervalles de prédiction est bien établie. Il vaut mieux utiliser des données simulées pour lesquelles la vérité est connue et toutes les hypothèses retenues.
Greg Snow
1
@GregSnow: D'après ce que j'ai décrit ci-dessus, vous obtiendrez sans aucun doute l'intervalle de prédiction. Notez que les intervalles de prédiction sont généralement beaucoup plus larges que les intervalles de confiance car les intervalles de confiance spécifient en fait où se situe la moyenne statistique d'une quantité, alors que la prédiction ne concerne qu'une observation, d'où une incertitude plus grande et donc des intervalles plus grands. Les 1 000 prédictions que vous recevez de 1 000 arbres peuvent être considérées comme un échantillon initial et vous n'avez pas besoin d'appliquer les hypothèses de normalité ici. Même une analyse par décile simple donnera de bons résultats.
5
@SashikanthDareddy, ce que vous décrivez ne sera certainement pas un intervalle de prédiction. Un intervalle de prédiction est déterminé par plus que simplement être plus large. Oui, les arbres individuels forment un bootstrap, mais le bootstrap estime des paramètres et non des valeurs individuelles. L'intervalle de prédiction est très dépendant de la distribution des points individuels. Le fait que votre méthode donne un intervalle pour les proportions avec un résultat catégoriel au lieu des catégories le prouve. Voir mon exemple dans la réponse ajoutée.
Greg Snow
0

J'ai essayé quelques options (tout cela en WIP):

  1. En fait, j'ai fait de la variable dépendante un problème de classification avec les résultats sous forme de plages, au lieu d'une valeur unique. Les résultats que j'ai obtenus étaient médiocres, comparés à l'utilisation d'une valeur simple. J'ai abandonné cette approche.

  2. Je l'ai ensuite convertie en plusieurs problèmes de classification, chacun représentant une limite inférieure pour la plage (le résultat étant que le modèle traverse ou non la limite inférieure), puis j'ai exécuté tous les modèles (~ 20), puis combiné le résultat pour obtenir une réponse finale sous forme de plage. Cela fonctionne mieux que 1 ci-dessus, mais pas aussi bon que j'en ai besoin. Je travaille toujours pour améliorer cette approche.

J'ai utilisé des estimations hors-programme et hors-programme pour décider si mes modèles sont bons ou mauvais.

Nouveau record
la source
0

Le problème de la construction d'intervalles de prévision pour les prévisions aléatoires de forêt a été traité dans le document suivant:

Zhang, Haozhe, Joshua Zimmerman, Dan Nettleton et Daniel J. Nordman. "Intervalles de prédiction aléatoire des forêts." Le statisticien américain, 2019.

Le package R "rfinterval" est son implémentation disponible au CRAN.

Installation

Pour installer le package R rfinterval :

#install.packages("devtools")
#devtools::install_github(repo="haozhestat/rfinterval")
install.packages("rfinterval")
library(rfinterval)
?rfinterval

Usage

Démarrage rapide:

train_data <- sim_data(n = 1000, p = 10)
test_data <- sim_data(n = 1000, p = 10)

output <- rfinterval(y~., train_data = train_data, test_data = test_data,
                     method = c("oob", "split-conformal", "quantreg"),
                     symmetry = TRUE,alpha = 0.1)

### print the marginal coverage of OOB prediction interval
mean(output$oob_interval$lo < test_data$y & output$oob_interval$up > test_data$y)

### print the marginal coverage of Split-conformal prediction interval
mean(output$sc_interval$lo < test_data$y & output$sc_interval$up > test_data$y)

### print the marginal coverage of Quantile regression forest prediction interval
mean(output$quantreg_interval$lo < test_data$y & output$quantreg_interval$up > test_data$y)

Exemple de données:

oob_interval <- rfinterval(pm2.5 ~ .,
                            train_data = BeijingPM25[1:1000, ],
                            test_data = BeijingPM25[1001:2000, ],
                            method = "oob",
                            symmetry = TRUE,
                            alpha = 0.1)
str(oob_interval)
xiaolongmao
la source
1
Bienvenue sur le site, @ xiaolongmao.Vous voudrez peut-être faire notre tour . S'il vous plaît ne pas poster des réponses identiques à plusieurs discussions. Essayez de personnaliser vos réponses à la question spécifique sur chaque fil. Si vous pensez vraiment qu'une réponse identique répond complètement à la question, cela signifie que la question est un doublon. Lorsque vous atteignez 50 points de réputation, vous pouvez poster un commentaire sur l'OP. Dans l'intervalle, vous pouvez marquer le Q de fermeture comme un doublon.
gung - Rétablir Monica