Quelle est l'utilisation appropriée de scale_pos_weight dans xgboost pour les jeux de données déséquilibrés?

26

J'ai un ensemble de données très déséquilibré. J'essaie de suivre les conseils de réglage et d'utilisation, scale_pos_weightmais je ne sais pas comment dois-je le régler.

Je peux voir que cela RegLossObj.GetGradientfait:

if (info.labels[i] == 1.0f) w *= param_.scale_pos_weight

donc un gradient d'un échantillon positif aurait plus d'influence. Cependant, selon l' article xgboost , la statistique du gradient est toujours utilisée localement = dans les instances d'un nœud spécifique dans une arborescence spécifique:

  1. dans le cadre d'un nœud, pour évaluer la réduction de perte d'un split candidat
  2. dans le cadre d'un nœud feuille, pour optimiser le poids donné à ce nœud

Il n'y a donc aucun moyen de savoir à l'avance ce qui serait un bien scale_pos_weight- c'est un nombre très différent pour un nœud qui se retrouve avec un rapport 1: 100 entre les instances positives et négatives, et pour un nœud avec un rapport 1: 2.

Des indices?

ihadanny
la source
Vous pouvez probablement régler le paramètre dans CV avec 5 fois 5 répétitions. Mais, vous devrez peut-être écrire le code pour ce faire.
user2149631

Réponses:

22

Généralement, le Scale_pos_weight est le rapport du nombre de classe négative à la classe positive. Supposons que l'ensemble de données comporte 90 observations de classe négative et 10 observations de classe positive, la valeur idéale de scale_pos_Weight doit être 9. Vous pouvez vérifier le lien suivant. http://xgboost.readthedocs.io/en/latest/parameter.html

Harshit Mehta
la source
1
Comment cela s'appliquerait-il à un ensemble de données multiclasse? Que diriez-vous de 28 classes? Ce n'est pas clair pour moi
Gabriel Ziegler
1
@Gabriel Je pense qu'alors il serait préférable d'opter pour des poids de classe. Vous pouvez utiliser scale_pos_weight, en utilisant une approche vs vs repos. Par exemple, créez des mannequins pour 28 classes. Ensuite, vous pouvez utiliser chacun d'eux comme un problème de classification binaire. De cette façon, vous aurez affaire à 28 modèles différents.
Harshit Mehta
Je vois, mais quand j'utilise onevsrest, le classificateur ne me donne pas également une sortie multi-étiquettes, non? Pas une seule classe sur 28
Gabriel Ziegler
Comment ?. Par exemple: les classes sont A, B, C. Vous pouvez donc avoir un classificateur binaire pour classer (A / Not A), un autre serait (B / Not B). Vous pouvez le faire pour 'n' nombre de classes. Ensuite, parmi toutes les probabilités correspondant à chaque classificateur, vous devez trouver un moyen d'affecter des classes.
Harshit Mehta
J'ai l'habitude d'utiliser onevsrest pour le multi-label, mais je vais essayer! Merci!
Gabriel Ziegler
3

Toute la documentation indique que cela devrait être:

scale_pos_weight = count(negative examples)/count(Positive examples)

En pratique, cela fonctionne plutôt bien, mais si votre jeu de données est extrêmement déséquilibré, je vous recommande d'utiliser quelque chose de plus conservateur comme:

scale_pos_weight = sqrt(count(negative examples)/count(Positive examples)) 

Ceci est utile pour limiter l'effet d'une multiplication d'exemples positifs par un poids très élevé.

deltascience
la source
1

Je comprends votre question et votre frustration, mais je ne suis pas sûr que ce soit quelque chose qui pourrait être calculé analytiquement, vous devriez plutôt déterminer un bon paramètre empiriquement pour vos données, comme vous le faites pour la plupart des hyper-paramètres, en utilisant la validation croisée comme @ user2149631 suggéré. J'ai eu un certain succès en utilisant SelectFPR avec Xgboost et l'API sklearn pour abaisser le FPR pour XGBoost via la sélection de fonctionnalités à la place, puis en ajustant davantage le scale_pos_weight entre 0 et 1.0. O.9 semble bien fonctionner mais comme pour tout, YMMV en fonction de vos données. Vous pouvez également pondérer chaque point de données individuellement lors de son envoi à XGboost si vous consultez leurs documents. Vous devez utiliser leur API et non l'encapsuleur sklearn. De cette façon, vous pouvez pondérer un ensemble de points de données beaucoup plus haut que l'autre, et cela aura un impact sur l'algorithme de boost qu'il utilise.

Simon
la source
0

Je suis également tombé sur ce dilemme et je cherche toujours la meilleure solution. Cependant, je vous suggère d'utiliser des méthodes telles que la recherche de grille (GridSearchCV dans sklearn) pour le meilleur réglage des paramètres pour votre classificateur. Cependant, si votre ensemble de données est fortement déséquilibré, il vaut la peine d'envisager des méthodes d'échantillonnage (en particulier les méthodes de suréchantillonnage aléatoire et SMOTE) et de modéliser l'ensemble sur des échantillons de données avec différents ratios d'exemples de classe positifs et négatifs. Voici un tutoriel agréable et utile (presque complet) sur la gestion des jeux de données déséquilibrés.

https://www.analyticsvidhya.com/blog/2017/03/imbalanced-classification-problem/

Bikash Joshi
la source