Suggestions pour un apprentissage sensible aux coûts dans un environnement très déséquilibré

15

J'ai un ensemble de données avec quelques millions de lignes et ~ 100 colonnes. Je voudrais détecter environ 1% des exemples dans l'ensemble de données, qui appartiennent à une classe commune. J'ai une contrainte de précision minimale, mais en raison d'un coût très asymétrique, je ne suis pas trop intéressé par un rappel particulier (tant qu'il ne me reste pas 10 correspondances positives!)

Quelles sont les approches que vous recommanderiez dans ce cadre? (liens vers les articles bienvenus, liens vers les implémentations appréciés)

em70
la source

Réponses:

15

J'ai trouvé que lui et Garcia (2009) sont une revue utile de l'apprentissage dans les problèmes de classe déséquilibrés. Voici quelques éléments certainement non exhaustifs à considérer:

Approches basées sur les données:

On peut sous-échantillonner la classe majoritaire ou suréchantillonner la classe minoritaire. (Breiman a souligné que cela équivaut formellement à attribuer des coûts de classification erronée non uniformes.) Cela peut poser des problèmes: le sous-échantillonnage peut faire en sorte que l'apprenant rate certains aspects de la classe majoritaire; le suréchantillonnage augmente le risque de sur-ajustement.

Il existe des méthodes de «sous-échantillonnage éclairé» qui réduisent ces problèmes. L'un d'eux est EasyEnsemble , qui échantillonne indépendamment plusieurs sous-ensembles de la classe majoritaire et crée plusieurs classificateurs en combinant chaque sous-ensemble avec toutes les données de la classe minoritaire.

SMOTE (Synthetic Minority Oversampling Technique) ou SMOTEBoost (combinant SMOTE avec boosting) créent des instances synthétiques de la classe minoritaire en faisant des voisins les plus proches dans l'espace des fonctionnalités. SMOTE est implémenté dans R dans le package DMwR (qui accompagne le livre de Luis Torgo «Data Mining with R, learning with case studies» CRC Press 2016 ).

Approches d'ajustement des modèles

Appliquez des pondérations spécifiques à la classe dans votre fonction de perte (pondérations plus importantes pour les cas minoritaires).

Pour les approches basées sur les arbres, vous pouvez utiliser la distance de Hellinger comme fonction d'impureté des nœuds, comme le préconisent Cieslak et al. "Les arbres de décision de distance Hellinger sont robustes et insensibles à l'inclinaison" ( code Weka ici .)

Utilisez un classificateur à une classe , en apprenant (selon le modèle) une densité de probabilité ou une limite pour une classe et en traitant l'autre classe comme des valeurs aberrantes.

Bien sûr, n'utilisez pas la précision comme métrique pour la construction de modèles. Le kappa de Cohen est une alternative raisonnable.

Approches d'évaluation des modèles

Si votre modèle renvoie des probabilités prédites ou d'autres scores, choisissez un seuil de décision qui effectue un compromis approprié en matière d'erreurs (en utilisant un ensemble de données indépendant de la formation et des tests). Dans R, le package OptimalCutpoints implémente un certain nombre d'algorithmes, y compris ceux sensibles au coût, pour décider d'une coupure.

MattBagg
la source
Merci pour la réponse détaillée. J'ai essayé de sous-échantillonner et j'ai lamentablement échoué. Les modèles présentent d'excellentes performances dans l'échantillon, mais le déséquilibre est toujours présent dans l'ensemble de test (et les données réelles que j'utiliserai finalement), de sorte que la précision OOS des modèles est horrible. J'ai également essayé des poids spécifiques à une classe, mais mon application implique un coût plus facilement quantifiable pour les faux positifs que pour les faux négatifs. En ce qui concerne les classificateurs d'une classe, j'ai essayé d'ajuster un svm linéaire (ceux non linéaires sont trop lents) et qui a 0 précision même dans l'échantillon ...
em70
1
Je compatis. La haute précision est difficile si la grande majorité de vos cas sont négatifs. J'utiliserais des poids spécifiques à la classe (comme inversement proportionnels à la fraction des cas dans la classe) pour apprendre et enregistrer les poids spécifiques au type d'erreur pour déterminer le seuil de décision. J'espère que vous utilisez la validation croisée avec le kappa de Cohen et non la précision pour la sélection du modèle. Je visualiserais la densité de probabilités pour les classes dans les données d'étalonnage ainsi que la précision latérale et l'enrichissement (précision / proportion de cas positifs) à tous les seuils pour vraiment comprendre les compromis disponibles.
MattBagg
Excellente réponse, merci. J'utilise une technique similaire à l'EasyEnsemble mentionné depuis un certain temps, mais en doutais (malgré des performances sensibles sur des données simulées). Maintenant, je sais que cela a du sens.
ayorgo
5

D'après ce que je comprends, il s'agit d'un domaine de recherche actif dans la communauté de l'apprentissage automatique et il n'y a pas de bonnes réponses, mais plutôt un nombre important et croissant de solutions potentielles. Vous obtiendrez probablement de meilleures réponses si vous spécifiez les algorithmes spécifiques que vous envisagez.

Si vous utilisez un modèle paramétrique (régression logistique), cela devrait être moins problématique et vous pouvez simplement faire varier le seuil en fonction de votre fonction de perte (coût des faux négatifs aux faux positifs)

Si vous utilisez des algorithmes d'apprentissage automatique, cela pourrait être plus difficile. Max Kuhn fait une tentative juste de résumer le problème dans le chapitre 16 de "Modélisation prédictive appliquée". Mais un sujet difficile à résumer. Si vous ne voulez pas acheter le livre, le code R est disponible dans le package AppliedPredictiveModeling pour ce chapitre et peut être suffisant en fonction de votre connaissance de R et des algorithmes utilisés.

Habituellement, la discussion tourne autour des algorithmes de sous-échantillonnage / suréchantillonnage +/- sensibles aux coûts. Avec des variations comme jous-boost également possibles.
Un exemple de ce type de discussion: Chen et al «Utilisation de la forêt aléatoire pour apprendre des données déséquilibrées» http://statistics.berkeley.edu/sites/default/files/tech-reports/666.pdf

Charles
la source
Le problème avec la variation du seuil est que c'est comme changer l'interception d'un modèle de régression. En réalité, je souhaiterais peut-être changer le vecteur de poids pour tenir compte des coûts. Mais si je fais ça, vu le déséquilibre déjà sévère, je me retrouve avec 0 précision! Je n'ai pas opté pour un algorithme et je dispose de ressources pour mettre en œuvre des idées de recherche de pointe, si elles sont prometteuses. Je vais jeter un œil au livre que vous avez suggéré.
em70
Le chapitre est moyen. Effort solide, mais sujet difficile à résumer. Beaucoup de revendications non prises en charge publiées sur diverses méthodes. Je pense que le sous-échantillonnage stratifié dans les forêts aléatoires est un bon début du point de vue de l'apprentissage automatique. Le code est dans le package du livre.
charles
0

Vous pouvez jeter un œil à l'implémentation de scikit-learn. faites attention à l'argument class_ weight qui peut avoir des valeurs d'un dictionnaire de poids de classe ou 'auto':

class sklearn.svm.SVC (C = 1.0, kernel = 'rbf', degree = 3, gamma = 0.0, coef0 = 0.0, rétrécissement = True, probabilité = False, tol = 0.001, cache_size = 200, class_weight = None, verbose = Faux, max_iter = -1, random_state = Aucun)

Vous pouvez jouer avec la valeur de l'argument class_weight qui peut être un dictionnaire de poids de classe ou 'auto'. En mode «auto», l'algorithme d'apprentissage attribuera automatiquement des poids à chaque classe en fonction du nombre d'échantillons dans chacun d'eux.

scikit-learn possède plusieurs autres algorithmes de classification, dont certains acceptent les pondérations de classe.

Cendre
la source
Pouvez-vous en dire plus sur la façon dont les pondérations de classe peuvent être utilisées pour atteindre les objectifs du PO? Je pense que cela est implicite dans votre message, mais ce n'est pas encore tout à fait une réponse.
gung - Rétablir Monica
Oui, l'argument class_weight peut avoir une valeur 'auto' si certains regardent dans la documentation ou il peut avoir une valeur de dictionnaire qui a les poids de classe. En cas d'auto, l'algorithme d'apprentissage lui-même trouve le poids de chaque classe en fonction du nombre d'échantillons dans chacune.
Ash