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 à strata
in 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.
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.
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.
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
.