web-dev-qa-db-fra.com

comment utiliser classwt dans randomForest of R?

J'ai un ensemble de données très déséquilibré avec des instances de classe cible dans le ratio suivant (edit :)  60000: 1000: 1000: 1000 60000:1000:1000:50 (c'est-à-dire un total de 4 classes). Je veux utiliser randomForest pour faire des prédictions de la classe cible.

Donc, pour réduire le déséquilibre de classe, j’ai joué avec le paramètre sampsize en le réglant sur (edit :)  c(5000, 1000, 1000, 1000) c(5000, 1000, 1000, 50) et quelques autres valeurs, mais elles n'ont pas été beaucoup utilisées. En fait, la précision de la 1ère classe a diminué lorsque j'ai joué avec sampsize, bien que l'amélioration des prédictions des autres classes ait été très minime.

En fouillant dans les archives, je suis tombé sur deux autres fonctionnalités de randomForest(), qui sont strata et classwt, qui sont utilisées pour compenser le problème de déséquilibre de classe.

Tous les documents sur classwt étaient anciens (appartenant généralement aux années 2007, 2008), ce qui suggère de ne pas utiliser la fonctionnalité classwt du paquet randomForest dans R car il n'implémente pas complètement sa fonctionnalité complète comme dans fortran. La première question est donc:
classwt est-il complètement implémenté maintenant dans le paquet randomForest de R? Si oui, que signifie le fait de passer c(1, 10, 10, 10) à l'argument classwt? (en supposant le cas ci-dessus de 4 classes dans la variable cible)

Un autre argument censé compenser le déséquilibre des classes est l’échantillonnage stratifié, qui est toujours utilisé avec sampsize. Je comprends ce que sampsize contient de la documentation, mais il n’ya pas assez de documentation ou d’exemples permettant de comprendre clairement comment utiliser strata pour surmonter le problème de déséquilibre de classe. La deuxième question est donc:
Quels types d'arguments doivent être passés à stratain randomForest et que représente-t-il?

J'imagine que le mot weight que je n'ai pas explicitement mentionné dans la question devrait jouer un rôle majeur dans la réponse.

24
StrikeR

classwt est correctement passé à randomForest, vérifiez cet exemple:

library(randomForest)
rf = randomForest(Species~., data = iris, classwt = c(1E-5,1E-5,1E5))
rf

#Call:
# randomForest(formula = Species ~ ., data = iris, classwt = c(1e-05, 1e-05, 1e+05)) 
#               Type of random forest: classification
#                     Number of trees: 500
#No. of variables tried at each split: 2
#
#        OOB estimate of  error rate: 66.67%
#Confusion matrix:
#           setosa versicolor virginica class.error
#setosa          0          0        50           1
#versicolor      0          0        50           1
#virginica       0          0        50           0

Les poids de classe sont les a priori des résultats. Vous devez les équilibrer pour obtenir les résultats souhaités.


Sur strata et sampsize cette réponse pourrait être utile: https://stackoverflow.com/a/20151341/2874779

En général, sampsize avec la même taille pour toutes les classes semble raisonnable. strata est un facteur qui sera utilisé pour le rééchantillonnage stratifié. Dans votre cas, vous n'avez pas besoin de saisir quoi que ce soit.

3

Les forêts aléatoires ne sont probablement pas le bon classificateur pour votre problème car elles sont extrêmement sensibles au déséquilibre des classes.

Quand j'ai un problème déséquilibré, je le traite habituellement en utilisant sampsize comme vous avez essayé. Cependant, toutes les strates sont égales en taille et j'utilise un échantillonnage sans remplacement. L'échantillonnage sans remplacement est important ici, car sinon, les échantillons des plus petites classes contiendront beaucoup plus de répétitions et la classe sera toujours sous-représentée. Il peut être nécessaire d’augmenter mtry si cette approche conduit à de petits échantillons, voire même au nombre total d’entités.

Cela fonctionne bien lorsqu'il y a suffisamment d'éléments dans la plus petite classe. Cependant, votre plus petite classe ne compte que 50 objets. Je doute que vous obteniez des résultats utiles avec sampsize=c(50,50,50,50).

De plus, classwt n'a jamais fonctionné pour moi.

1
Daniel Mahler

Vous pouvez passer un vecteur nommé à classwt. Mais le calcul du poids est très délicat.

Par exemple, si votre variable cible y a deux classes "Y" et "N" et que vous souhaitez définir une pondération équilibrée, vous devez procéder comme suit:

wn = sum(y="N")/length(y)
wy = 1

Puis définissez classwt = c("N"=wn, "Y"=wy) 

Vous pouvez également utiliser le package ranger. Ce paquet offre des constructions flexibles de forêts aléatoires, et il est facile de spécifier le poids de la classe/de l’échantillon. ranger est également pris en charge par le package caret.

0
West Yang