Machin learning et réduction de dimension

quand réduire le nombre de dimensions ?

a marqué ce sujet comme résolu.

Bonjour à tous,

je me pose quelques questions pratiques pour mon premier projet de machin learning. Mon problème consiste à prédire le défaut des entreprises (credit scoring), avec une variable DEFAULT qui vaut 1 si l’entreprise à fait défaut et 0 sinon. Je dispose pour cela d’un dataset avec 130 features (plus l’output) et 4400 observations, sans aucune données manquantes.

J’ai réduit mes features à 110 features car 20 colonnes ont une variance nulle après analyse.

Je me demande si je dois encore réduire mon nombre de features ou pas ? Est-ce que 110 features pour 4400 observations c’est de trop ou pas ? Existe il des astuces pour savoir si le nombre de features est trop elevé ou pas ? Quand décider de faire de réduction de dimension ou pas ?

Merci d’avance pour vos réponses :)

+0 -0

En fonction de l’algorithme que tu utilises, ce dernier sera (ou non !) capable de t’indiquer les features les moins utiles (c’est à dire qu’elles sont partagées par trop de label dans ton dataset).

Après, parfois, passer à de grandes dimensions peut être un atout plus qu’une faiblesse notamment pour rester généraliste.

Il n’y a pas de reponse absolue. Tu peux avoir une petite idee en faisant une PCA et en regardant les valeurs propres associees a chaque feature, de sorte que tu peux ensuite fixe la quantite d’information que tu veux garder (e.g. si les 5 premieres features represente 95% de l’information, c’est peut etre suffisant).

Par curiosite, il y a moyen que tu partages le jeu de donnees?

EDIT: Il faut aussi prendre en compte l’ensemble des valeurs que peuvent prendre tes features. Si tu as un jeu de donnee avec 3 variables mais qu’elles peuvent prendre 10 millions de valeurs, c’est surement plus complique d’en faire quelque chose a priori que 100 variables binaires.

+0 -0

Je rejoins artragis, beaucoup de dimensions n’est pas forcément une mauvaise chose. Le problème est que tu ne sais pas s’il existe des sous-groupes qui ont un "prédictibilité" supérieure ou des paramètres que vous n’avez pas mesuré qui sont de bons indicateurs.

C’est le problème avec les analyses basées sur la variance totale, comme ce que tu as fait avec la variance nulle ou avec la PCA. Si par exemple, tu as un sous-groupe de 100 entreprises, qui possède une parametres très prédictif (ou plusieurs gros sous-groupes qui "équilibrent" leurs variances entre eux). Avec une analyse sur la variance totale, ce groupe pourrait avoir une variance très faible par rapport à la variance totale et être masqué. Alors qu’en terme de prédiction, ce groupe serait très intéressant à conserver.

+1 -0

Pour moi, 110 features pour 4400 individus, ça me paraît beaucoup. Très gros risque d’avoir des variables redondantes.

D’autant plus que je vois mal quels sont ces 110 indicateurs qu’on peut collecter pour ’cataloguer’ une entreprise.

Mais ceci-dit, tu peux déterminer toi-même si tu as trop de données.

  1. tu mets de côté 400 entreprises. (et tu répéteras l’opération 11 fois, en isolant à chaque fois 400 entreprises).

  2. tu fais tourner ton ML sur les 4000 autres entreprises. ça va te donner un modèle. Tu appliques ce modèle d’une part aux 4000 entreprises (jeu 1), et d’autre part aux 400 entreprises mises à part (jeu 2).

Si ton modèle donne de très bons résultats sur le jeu de données 1, et des résultats mitigés sur le jeu de données 2, c’est qu’il y a ’overfitting’, autrement dit, c’est que tu as trop de features.

Le modèle a exploité des données quasi-redondantes, pour parfaitement fitter à la cible. Mais en propageant cela aux 400 autres entreprises, ça donne de mauvaises prédictions.

Mon explication est très terre-à-terre, mais en cherchant le mot ’overfitting’, tu devrais trouver plein de choses. Tu vas même peut-être tomber sur un très bon tutoriel publié sur ZdS il y a 2 ou 3 ans.

Sans connaître les données et les approches utilisées, ca me semble dur de donner des conseils. J’ai déjà bossé sur des modèles avec plusieurs milliers de variables indépendantes et les méthodes de feature extraction n’étaient pas du tout bonnes. De plus, comme déjà dit, certaines approches sont plus performantes sans réduire les dimensions a priori (puisque la réduction de dimensions est indépendante de l’apprentissage et donc ne peut être optimisé selon la qualité de la prédiction). Idem pour la cross validation (ce dont parle Elegance), certains modèles intègrent ca directement.

Quand décider de faire de réduction de dimension ou pas ?

Du coup, pour répondre à cette question : ca dépend des algos que tu veux utiliser. Tu ne peux pas étudier cette question indépendamment du choix de l’algo d’apprentissage.

+2 -0

Par curiosite, il y a moyen que tu partages le jeu de donnees?

C’est le prof qui nous à fourni le dataset qui est extrait d’un data set réel de Capgemini chez qui il travaille, donc je ne pense pas qu’on ai le droit de le diffuser malheureusement. :(

Sans connaître les données et les approches utilisées, ca me semble dur de donner des conseils. Du coup, pour répondre à cette question : ca dépend des algos que tu veux utiliser. Tu ne peux pas étudier cette question indépendamment du choix de l’algo d’apprentissage.

En fait on nous à donné le dataset et on doit en faire ce qu’on veut, sachant que nous n’avons jamais eu aucun cours de machin learning (ni de programmation^^). J’ai heureusement déjà un minimum de lectures sur le sujet, mais c’est la première fois que je suis confronté à la mise en pratique de ces techniques. Et clairement mes connaissances restent superficielles, je comprends les différents types de modèles et leurs fonctionnement dans les grandes lignes, mais quand il s’agit de choisir un modèle parmi la multitude de variances et combinaisons qui existent ainsi que les différents paramètres et hyper-paramètres…

Je n’ai donc pas vraiment la moindre idée en soit de quels algos utiliser, si ce n’est essayer de tester un peu tous les trucs basiques en classification et voir ce que ça donne. :p

Si ton modèle donne de très bons résultats sur le jeu de données 1, et des résultats mitigés sur le jeu de données 2, c’est qu’il y a ’overfitting’, autrement dit, c’est que tu as trop de features.

J’ai entrainé (avec un 10 fold cross validation quand c’est possible) quelques modèles de base pour l’instant (regression logistique, knn, svm, random forest, boosted regression) et je n’ai jamais de problèmes d’over fiting, mes résultats en entrainement et en test sont similaires (j’ai 70% des données en entrainement et 30% en test).

Je crois que finalement mon soucis principal n’est pas l’over fitting mais la modélisation en tant que telle.

Le problème est que mes données sont très déséquilibrées par nature : 93% des entreprises ne font pas défaut et 7% font défaut. Ainsi on obtient facilement une acuracy très élevée (plus de 90% à chaque fois) et une spécificité aussi élevée. Le problème est que la sensibilité des modèles (la capacité à détecter correctement les entreprises qui font faillite) est le plus important critère. En effet prêter à une entreprise qui fera faillite (faux négatif) peut conduire à des pertes économiques importantes alors que ne pas prêter à une entreprise qui ne fera pas faillite (faux positif) conduit à un manque a gagné minimum (les intérêts qu’on aurait gagné en prêtant).

Le problème est que tous mes modèles ont une sensibilité très faible et sont incapable d’apprendre correctement à prédire les défauts. Ma random forest à ainsi une sensibilité de littéralement 0%, elle classe toutes les entreprises en non défaut… Mon meilleur modèle, un Naive Bayes, obtient un score de 50% en sensibilité, tout en restant à 85% en spécificité. Sinon les autres ont une sensibilité entre 10% et 30%.

J’ai essayer de chercher comment demander à mes modèles de maximiser plutôt la spécificité. Mon package R comporte une variable metric = "Sens" qui indique la métrique de sélection des meilleurs modèles, mais que j’utilise ça au lieu de l’Accuracy ou du Kappa ne change quasiment rien aux résultats malheureusement…

Tous mes modèles sont entrainés avec le package Carret qui choisit lui même les meilleurs paramètres du modèle. Par exemple pour un knn :

1
2
3
4
5
6
7
8
knn_model = train(DEFAULT~., 
          data = training_set,
          trControl = train_control, 
          method = "kknn",
          metric = "Sens")
prediction = predict(knn_model, testing_set) 
conf_matrix = confusionMatrix(prediction, testing_set$DEFAULT)
print(conf_matrix)

La librairie choisie elle-même la distance optimale et le k du modèle, ce qui est bien pratique quand on ne connait pas exactement soit-même l’impact des paramètre et qu’on a aucune idée sur quel set de paramètres essayer plutôt qu’un autre.

J’ai essayé de tester des modèles plus avancées, mais la liste de modèles disponibles est juste énorme et je n’ai pas la moindre idée de ce qu’il faudrait plutôt tester ou pas.

J’ai par exemple testé une random foret avec adaboost et outre les 2heures que j’ai perdu, le modèle était certes plus efficace qu’une random forest classique (qui avait 0% de sensibilité^^) mais le résultat restait terriblement mauvais. Je me dis que les random forests semblent un mauvais candidat pour mon problème à priori non ?

A l’inverse mon naive bayes à donné les meilleurs résultats, je pensait tester différents algorithmes qui s’en inspirent, mais lesquels ? En prenant des modéles avec le nom "baysian" au hasard dans ce que carret propose j’ai juste réussit… à planter mon ordinateur par manque de ram. J’ai 12go de ram mais a chaque fois le modèle veut allouer des vecteurs de 6go alors qu’il utilise déjà 7go ce qui conduit à l’arrêt de l’entrainement.

Existe-il des modèles qui sont plus efficaces que d’autres quand les classes à prédire sont totalement déséquilibrées comme dans mon cas ? Devrait-je continuer avec des classificateurs baysiens en essayant de les booster ou de les combiner à d’autres techniques ? Dois-je tester des réseaux de neurones ? Il y a il a priori des types de neurones/fonctions d’activations qui semblent adaptées à mon problème ?

+0 -0

J’ai entrainé (avec un 10 fold cross validation quand c’est possible) quelques modèles de base pour l’instant (regression logistique, knn, svm, random forest, boosted regression) et je n’ai jamais de problèmes d’over fiting, mes résultats en entrainement et en test sont similaires (j’ai 70% des données en entrainement et 30% en test).

Comment peux-tu avoir un split 70-30 avec un 10 x-validation qui implique un split 90-10? Quand est-ce que ce n’est pas possible d’utiliser une cross-validation ? Parce que normalement si le soucis c’est la prevalence d’une de tes classes, cela se contourne par une stratification.

Le problème est que mes données sont très déséquilibrées par nature : 93% des entreprises ne font pas défaut et 7% font défaut. Ainsi on obtient facilement une acuracy très élevée (plus de 90% à chaque fois) et une spécificité aussi élevée.

C’est un fait que je me tue a repeter en cours et meme au sein de mon lab mais la prevalence faible n’est jamais un probleme en soit. Ce sont les methodes qui ont un probleme et les artifices de validation sont tous imparfaits. Meme la stratification est mauvaise en soit parce qu’elle change artificiellement le systeme etudie et peu biaiser la comparison entre des methodes discriminative et des methodes generatives.

En classification binaire, l’indicateur phare a utiliser n’est ni l’accuracy, ni la ROC/AUC mais le coefficient de correlation de Matthew qui a le bon gout de prendre l’integralite de la matrice de confusion en compte. Le second indicateur clef c’est la PR-curve qui domine toujours la ROC-curve et ne souffre pas de ses defauts.

Plus d’info ici: https://www.biostat.wisc.edu/~page/rocpr.pdf

First, for any dataset, the ROC curve and PR curve for a given algorithm contain the same points. This equivalence, leads to the surprising theorem that a curve dominates in ROC space if and only if it dominates in PR space. Second, as a corollary to the theorem we show the existence of the PR space analog to the convex hull in ROC space, which we call achievable PR curve. Remarkably, when constructing the achievable PR curve one discards exactly the same points omit- ted by the convex hull in ROC space. Consequently, we can efficiently compute the achievable PR curve. […] Finally, we show that an algorithm that optimizes the area under the ROC curve is not guaranteed to optimize the area under the PR curve.

Mais en general, si ton jeu de donnee est representatif de la population, alors modifier la prevalence pour pouvoir utiliser des techniques classiques de validation est mal, parce que la distribution de probabilite d’apparation de tel ou tel input vector est ou peut etre utilise par la methode d’apprentissage pour selectionner le modele. Grosso-modo cela revient a violer une hypothese durant l’apprentissage en esperant que les resultats soient bon dans la vraie vie.

C’est tout a fait normal puisque la distribution de probabilite $\mu$ des points de $X$, l’espace des inputs, apparait dans l’erreur de generalisation:

$\int_X ||h(x) - f(x)||\mu(x)dx$ avec $h$ le model construit, $f$ la fonction inconnue et $||.||$ un norme sur $Y$.

Pire, si une methode n’utilise pas cette information, elle ne sera pas affectee compare a une methode qui donnera de moins bon results que ce qu’elle aura pu obtenir dans la vraie vie (j’ai typiquement un exemple du paquet ROOT du CERN qui a probablement nique un paquet de publications de physiciens sur la comparaison de methode parce qu’il reequilibre automatiquement la prevalence de chaque classe et on s’est appercu qu’en pratique la methode selectionnee de cette maniere sur le jeu de donnees n’etait pas la meilleure methode en production).

Bref, essaye surtout d’optimiser les PR-curve et le coefficient de Matthew. Si c’est pas possible, le F1-score est deja une meilleure metrique que l’accuracy ou la ROC pour les jeux desequilibres. Mais si tu peux faire sans techniques qui manipulent ton jeu de donnees, fait sans.

EDIT: Donc non, en tant que tel je ne conseille pas forcement de changer de methode mais d’essayer de changer la metrique a optimiser. La difficulte c’est que beaucoup de theorie a ete faite pour l’accuracy et que pour diverses raisons, les implementations ne permettent pas changer la metrique a optimiser (la raison c’est que cela requiererait des techniques de type black-box et divers surrogate models ou de la differentiation automatique pour calculer automatique le gradient - ce qui a un cout de calcul non negligeable en plus d’etre un sujet de recherche actuel - voire certaines methodes sont par construction faite uniquement pour optimiser l’erreur de classification et il n’y a rien a y faire). De memoire cela devrait etre possible avec Scikit learn et certaines methodes.

+0 -0

Comment peux-tu avoir un split 70-30 avec un 10 x-validation qui implique un split 90-10? Quand est-ce que ce n’est pas possible d’utiliser une cross-validation ? Parce que normalement si le soucis c’est la prevalence d’une de tes classes, cela se contourne par une stratification.

je veux dire que je sépare mon dataset en un training set avec 70% des données et un test set avec 30%. J’entraine et je valide mon modèle sur les 70% des données, et c’est là que je fais la cross validation pour choisir le modèle. Puis je test le résultat obtenu sur le testing set et je compare mes modèles entre eux à ce moment là.

En classification binaire, l’indicateur phare a utiliser n’est ni l’accuracy, ni la ROC/AUC mais le coefficient de correlation de Matthew qui a le bon gout de prendre l’integralite de la matrice de confusion en compte. Le second indicateur clef c’est la PR-curve qui domine toujours la ROC-curve et ne souffre pas de ses defauts.

Ok merci pour le lien et les infos, je n’avais jamais entendu parlé de ce coefficient de Matthew !

Meme la stratification est mauvaise en soit parce qu’elle change artificiellement le systeme etudie et peu biaiser la comparison entre des methodes discriminative et des methodes generatives.

Tu penses que je ne devrais donc pas stratifier mes données ? Je viens de voir que ma librairie parle de ce problème dans la documentation et qu’ils conseillent en effet de ne pas stratifier le testing set et d’appliquer des méthodes de re sempling pour le training set. Je vais essayer avec ces différentes méthodes et voir si cela change mes résultats, merci :)

Bref, essaye surtout d’optimiser les PR-curve et le coefficient de Matthew. Si c’est pas possible, le F1-score est deja une meilleure metrique que l’accuracy ou la ROC pour les jeux desequilibres.

Oui je suis bien conscient du problème, mais j’avoue ne pas encore bien comprendre comment en pratique dire à mon algorithme d’utiliser une autre métrique. J’ai essayé de passer le paramètre metric à "Sens" pour augmenter la sensibility mais je n’ai pas observé de différence significative. Que je lui passe "Sens", "Kappa" ou "ROC" comme metric de performance, les résultats sont assez proches à chaque fois (Sens améliore un peu les choses clairement, mais ça reste mauvais dans l’absolu, genre ma sensibility passe de 16% à 23%…^^).

Je n’ai pas l’impression que mon package propose par défaut les metric que tu m’indiques, je vais essayer de voir comment je peux les implémenter. C’est bizarre car il ne propose aucune liste des métriques existences, par exemple aucune trace de metric = "Sens"dans la doc alors que cette metric existe bien…

De memoire cela devrait etre possible avec Scikit learn et certaines methodes.

Le problème est que j’utilise R avec lequel je commence à être un minimum à l’aise, et à court terme je ne pas passer en python sur lesquel je n’ai jamais vraiment travaillé.

De façon globale je suis plutôt content de tes remarques, j’avais la bonne intuition en essayant de changer de metric. Après en pratique je vais voir ce que je peux faire avec les métriques que tu m’as indiqué et la question de la stratification des données, merci pour tes réponses :)

+0 -0

je veux dire que je sépare mon dataset en un training set avec 70% des données et un test set avec 30%. J’entraine et je valide mon modèle sur les 70% des données, et c’est là que je fais la cross validation pour choisir le modèle. Puis je test le résultat obtenu sur le testing set et je compare mes modèles entre eux à ce moment là.

Demandred

Ce n’est pas une approche standard. Normalement la 10 cross-validation consiste a decouper l’integralite de ton jeu de donnees en 90-10 et de faire tourner l’algorithme 10 fois sur les 10 fold obtenus et en utilisant le 10% restant a chaque fois pour tester le modele selectionne sur les 90%.

Si tu as une etape de calibration ou d’hyperparameter tuning, elle doit etre inclus dans la phase de selection sur les 90% du jeu initial et generalement on fait une ce qu’on appelle du nested cross-validation qui consiste a redecouper le fold d’entrainement de 90% en 90-10 (ou autre). Et la tu peux faire de l’hyperparameter tuning soit sur un seul run de ton split 90-10 ou de maniere plus robuste, sur les 10 folds internes.

Image utilisateur

De cette maniere, tu evites ce qu’on appelle le "data leak" (qui conduise a des resultats trop optimistes) et tu isoles a la fois la construction du modele, la calibration et la validation.

  1. https://chrisalbon.com/machine_learning/model_evaluation/nested_cross_validation/
  2. http://scikit-learn.org/stable/auto_examples/model_selection/plot_nested_cross_validation_iris.html
  3. https://stats.stackexchange.com/questions/65128/nested-cross-validation-for-model-selection

Et une derniere reference assez recente sur cette histoire de metrique a optimiser: http://proceedings.mlr.press/v54/eban17a/eban17a.pdf

+0 -0

Ce n’est pas une approche standard.

J’ai trouvé ça dans cet ouvrage. Si je comprends bien mon approche consiste juste à faire une cross validation sur le inner split et non sur le external split que je garde constant à 70%/30%. Je viens de lire, ils font bien la séparation entre données d’entrainnement/validation du modèle et données de test qui elles ne bougent pas et simulent de nouvelles données.

J’ai aussi trouvé pas mal de codes où les gens avaient une telle approche. Je viens de faire quelques tests, et que je fasse mon approche non standard ou un 10-fold cv classique sur toutes mes données mes résultats sont identiques. Tu penses que ça pose vraiment problème ?

Sinon en plus de cette histoire de cross validation j’ai testé différents trucs : - construire mon training set différemment en utilisant les fonctions de resempling de caret pour les cas de déséquilibre entre les classes. Cela ne fait pas une grande différence sur les 3 modèles que j’ai testé, quel que soit la méthode retenue parmi les 3 retenus. - Essayer d’ajouter une métrique personnalisée en reprenant le code proposé ici. Ca fonctionne, mais idem sur les 3 modèles testés pas vraiment de différence notable. De même que je prenne la metric Kappa, Sens ou Auc, les résultats ne changent quasiment jamais !

J’avoue ne plus trop savoir quoi faire, je commence à me dire que les 58% de mon naive Bayses ne sont pas si mal. Les slides du prof où il présente les résultats des vrais modéles qu’ils utilisent chez capgemini ne montrent que des ROC curve (alors que c’est une métrique peu pertinente^^) donc je ne sais pas dans l’absolu ce que sont de bonnes performances sur ce genre de données…

Merci pour les liens, regarderai tout ça pour mieux apprendre les différentes metrics et techniques de sélection de modèle/validation. :)

+0 -0

Bonjour,

Pour revenir sur la question de la réduction de dimension, voici quelques éléments de réflexion.

Les algorithmes de réduction de dimensionnalité sont (souvent) non-supervisés, c’est-à-dire qu’ils regardent la distribution des données. Si le dataset n’est pas équilibré, il est possible que l’algorithme se focalise sur de "mauvaises" corrélations.

Pour commencer, il faut sélectionner aléatoirement un sous-ensemble du dataset de telle façon à obtenir la même proportion d’éléments pour chaque classe. Pour illustrer l’intérêt de cette étape, tu peux calculer et afficher la matrice du corrélation pour quelques features avant et après sélection. Normalement, les deux matrices ne devraient pas avoir la même tête. Je serais intéressé de voir le résultat même si tu caches les noms des features pour les raisons que tu as évoquées plus haut.

Si tu as un peu de temps, tu peux essayer de voir s’il y a des aberrations (outliers) mais n’y passe pas trop de temps.

Pour terminer, il faut choisir la dimension de l’espace réduit. Si je prends le cas de l’algorithme PCA, il s’agit d’afficher "l’importance" de chaque axe de projection en regardant la quantité de variation selon cet axe. Ça paraît compliqué dit comme ça mais, c’est en fait assez simple.

Premièrement, il faut récupérer les valeurs propres de la matrice de corrélation. Une fois calculées, il faut prendre leur valeur absolue et les trier par ordre décroissant. Deuxièmement, il faut afficher un graphique donnant l’évolution des valeurs propres en valeur absolue (axe Y) contre leur indice dans le tableau trié (axe X). N’hésite pas à poster la courbe des valeurs propres.

La courbe obtenue doit être décroissante et strictement positive. Au début, tu devrais observer une chute assez rapide des valeurs puis un plateau légèrement décroissant. Le plateau signifie que les axes associés à ses valeurs propres ne contribuent que très peu à la reconstruction de l’information. C’est donc des axes qu’on décide de supprimer. Entre la chute rapide et le plateau, il y a ce qu’on appelle un coude dans la courbe. En sélectionnant uniquement les axes représentés par les valeurs propres à gauche du coude, on maximise l’information tout en minimisant le nombre de dimensions.

Bon courage pour la suite du projet !

Les algorithmes de réduction de dimensionnalité sont (souvent) non-supervisés, c’est-à-dire qu’ils regardent la distribution des données. Si le dataset n’est pas équilibré, il est possible que l’algorithme se focalise sur de "mauvaises" corrélations.

Pas necessairement. Si la distribution generatrice des donnees n’est pas uniforme, il n’y a pas de raison que cela pose des problemes. Il faut un echantillon qui represente la population dans la plupart des cas.

Pour commencer, il faut sélectionner aléatoirement un sous-ensemble du dataset de telle façon à obtenir la même proportion d’éléments pour chaque classe.

Encore une fois, uniquement si la distribution sous-jacente ne correspond pas a la distribution du jeu de donnees. Sinon (presque) aucun soucis, et contraire, faire du sampling dans ce cas correspond a faire une mauvaise hypothese sur la distribution des donnees (pas tres bayesien tout ca). Si vraiment il y a des soucis, e.g. une classe est tellement sous-representee que l’algorithme a du mal a apprendre correctement a classifier, on peut soit utiliser une methode d’oversampling type SMOTE ou du Boosting pour indiquer a l’algorithme que ces exemples sont importants/difficiles.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte