Rappel élevé - faible précision pour un ensemble de données déséquilibré

11

Je rencontre actuellement des problèmes lors de l'analyse d'un ensemble de données de tweet avec des machines à vecteurs de support. Le problème est que j'ai un ensemble d'entraînement en classe binaire déséquilibré (5: 2); qui devrait être proportionnelle à la distribution réelle des classes. Lors de la prédiction, j'obtiens une faible précision (0,47) pour la classe minoritaire dans l'ensemble de validation; le rappel est de 0,88. J'ai essayé d'utiliser plusieurs méthodes de suréchantillonnage et de sous-échantillonnage (effectuées sur l'ensemble d'apprentissage) qui n'ont pas amélioré la précision car l'ensemble de validation est également déséquilibré pour refléter la distribution réelle des classes. J'ai également implémenté différents coûts dans la machine à vecteurs de support, ce qui m'a aidé. Maintenant, il semble que je ne puisse plus améliorer mes performances.

Quelqu'un parmi vous a-t-il des conseils sur ce que je pourrais faire pour améliorer ma précision sans nuire à mon rappel? De plus, quelqu'un a-t-il une idée pourquoi j'obtiens beaucoup plus de faux positifs que de faux négatifs (positif est la classe minoritaire)?

Filippo Scopel
la source
3
Au moins une partie du problème consiste à évaluer le modèle sur la base d'une règle de notation incorrecte.
Sycorax dit Réintégrer Monica
Par «méthodes de suréchantillonnage et de sous-échantillonnage», avez-vous essayé SMOTE (Synthetic Minority Over-sampling Technique)? D'après mon expérience, cela a amélioré mon taux de classification de la classe minoritaire pour un ensemble de données déséquilibré de 300: 1.
Matthew Lau
Salut Matthew, merci pour ta réponse. J'ai essayé plusieurs méthodes de sous-échantillonnage et même d'assemblage, y compris toutes sortes de techniques SMOTE.
Filippo Scopel
2
Puisque vous utilisez scikit, essayez les arbres à gradient amélioré sur vos données. Vous obtiendrez probablement une meilleure ASC de rappel de précision dès la sortie de la boîte. Comme vous le faites remarquer, les SVC ne sont vraiment pratiques que pour de très petits ensembles de données.
rinspy
1
Salut Filippo! Je traite actuellement, je dirais, exactement le même problème que vous décrivez :-) J'ai essayé toutes les choses habituelles (suréchantillonnage / sous-échantillonnage, SMOTE, classe-poids) et j'ai même essayé plusieurs apprenants différents (SVM, Random Forest, réseaux de neurones entièrement connectés), mais l'effet est le même partout: rappel élevé de la classe minoritaire après application de SMOTE ou poids de classe, mais très faible précision. Avez-vous finalement trouvé une solution?
u_b

Réponses:

6

Quelqu'un a-t-il une idée pourquoi j'obtiens beaucoup plus de faux positifs que de faux négatifs (le positif est la classe minoritaire)? Merci d'avance pour votre aide!

Parce que positif est la classe minoritaire. Il existe de nombreux exemples négatifs qui pourraient devenir de faux positifs. À l'inverse, il y a moins d'exemples positifs qui pourraient devenir de faux négatifs.

Rappelons que Recall = Sensitivity=TP(TP+FN)

La sensibilité (True Positive Rate) est liée au taux de faux positifs (spécificité 1) tel que visualisé par une courbe ROC. À un extrême, vous qualifiez chaque exemple de positif et avez une sensibilité de 100% avec 100% de FPR. À un autre, vous n'appelez aucun exemple positif et avez une sensibilité de 0% avec un FPR de 0%. Lorsque la classe positive est minoritaire, même un FPR relativement petit (que vous pourriez avoir parce que vous avez un rappel élevé = sensibilité = TPR) finira par provoquer un nombre élevé de PF (car il y a tellement d'exemples négatifs).

Depuis

Précision=TP(TP+FP)

Même à un FPR relativement faible, le FP submergera le TP si le nombre d'exemples négatifs est beaucoup plus grand.

Alternativement,

Classificateur positif:C+

Exemple positif:O+

Précision =P(O+|C+)=P(C+|O+)P(O+)P(C+)

P (O +) est faible lorsque la classe positive est petite.

Quelqu'un parmi vous a-t-il des conseils sur ce que je pourrais faire pour améliorer ma précision sans nuire à mon rappel?

Comme mentionné par @rinspy, GBC fonctionne bien d'après mon expérience. Il sera cependant plus lent que SVC avec un noyau linéaire, mais vous pouvez créer des arbres très peu profonds pour l'accélérer. En outre, plus de fonctionnalités ou plus d'observations peuvent aider (par exemple, il peut y avoir une fonctionnalité actuellement non analysée qui est toujours définie sur une valeur dans l'ensemble de votre FP actuel).

Il peut également être utile de tracer des courbes ROC et des courbes d'étalonnage. Il se peut que même si le classifieur a une faible précision, cela pourrait conduire à une estimation de probabilité très utile. Par exemple, le simple fait de savoir qu'un disque dur peut avoir une probabilité de défaillance 500 fois plus élevée, même si la probabilité absolue est assez faible, peut être une information importante.

En outre, une faible précision signifie essentiellement que le classificateur renvoie un grand nombre de faux positifs. Cependant, cela pourrait ne pas être si mauvais si un faux positif est bon marché.

user0
la source
2

Méthodes à essayer:

Sous-échantillonnage:

Je suggère d'utiliser des techniques de sous-échantillonnage puis de former votre classificateur.

Imbalanced Learning fournit une API de style d'apprentissage scikit pour un ensemble de données déséquilibré et devrait être un bon point de départ pour l'échantillonnage et les algorithmes à essayer.

Bibliothèque : https://imbalanced-learn.readthedocs.io/en/stable/

SVM basé sur le classement:

Cela s'est révélé améliorer le rappel pour les systèmes de haute précision et est utilisé par Google pour détecter les mauvaises publicités. Je recommande de l'essayer.

Document de référence pour SVM:

https://static.googleusercontent.com/media/research.google.com/en//pubs/archive/37195.pdf

Vibhu Jawa
la source
1

L'approche standard serait de pondérer votre erreur en fonction de la fréquence des classes. Par exemple, si vous le faisiez en Python avec sklearn:

model = sklearn.svm.SVC(C=1.0, kernel='linear', class_weight='balanced')
model.fit(X, y)
mprat
la source
Salut mprat, merci pour votre réponse. J'ai déjà utilisé class_weight = équilibré.
Filippo Scopel