Je travaille sur un problème d'analyse des sentiments, les données ressemblent à ceci:
label instances
5 1190
4 838
3 239
1 204
2 127
Donc mes données sont déséquilibrées puisque 1190 instances
sont étiquetées avec 5
. Pour la classification Im utilisant le SVC de scikit . Le problème est que je ne sais pas comment équilibrer mes données de la bonne manière afin de calculer avec précision la précision, le rappel, l'exactitude et le score f1 pour le cas multiclasse. J'ai donc essayé les approches suivantes:
Première:
wclf = SVC(kernel='linear', C= 1, class_weight={1: 10})
wclf.fit(X, y)
weighted_prediction = wclf.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, weighted_prediction)
print 'F1 score:', f1_score(y_test, weighted_prediction,average='weighted')
print 'Recall:', recall_score(y_test, weighted_prediction,
average='weighted')
print 'Precision:', precision_score(y_test, weighted_prediction,
average='weighted')
print '\n clasification report:\n', classification_report(y_test, weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, weighted_prediction)
Seconde:
auto_wclf = SVC(kernel='linear', C= 1, class_weight='auto')
auto_wclf.fit(X, y)
auto_weighted_prediction = auto_wclf.predict(X_test)
print 'Accuracy:', accuracy_score(y_test, auto_weighted_prediction)
print 'F1 score:', f1_score(y_test, auto_weighted_prediction,
average='weighted')
print 'Recall:', recall_score(y_test, auto_weighted_prediction,
average='weighted')
print 'Precision:', precision_score(y_test, auto_weighted_prediction,
average='weighted')
print '\n clasification report:\n', classification_report(y_test,auto_weighted_prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, auto_weighted_prediction)
Troisième:
clf = SVC(kernel='linear', C= 1)
clf.fit(X, y)
prediction = clf.predict(X_test)
from sklearn.metrics import precision_score, \
recall_score, confusion_matrix, classification_report, \
accuracy_score, f1_score
print 'Accuracy:', accuracy_score(y_test, prediction)
print 'F1 score:', f1_score(y_test, prediction)
print 'Recall:', recall_score(y_test, prediction)
print 'Precision:', precision_score(y_test, prediction)
print '\n clasification report:\n', classification_report(y_test,prediction)
print '\n confussion matrix:\n',confusion_matrix(y_test, prediction)
F1 score:/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:676: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1082: DeprecationWarning: The default `weighted` averaging is deprecated, and from version 0.18, use of precision, recall or F-score with multiclass or multilabel data or pos_label=None will result in an exception. Please set an explicit value for `average`, one of (None, 'micro', 'macro', 'weighted', 'samples'). In cross validation use, for instance, scoring="f1_weighted" instead of scoring="f1".
sample_weight=sample_weight)
0.930416613529
Cependant, je reçois des avertissements comme celui-ci:
/usr/local/lib/python2.7/site-packages/sklearn/metrics/classification.py:1172:
DeprecationWarning: The default `weighted` averaging is deprecated,
and from version 0.18, use of precision, recall or F-score with
multiclass or multilabel data or pos_label=None will result in an
exception. Please set an explicit value for `average`, one of (None,
'micro', 'macro', 'weighted', 'samples'). In cross validation use, for
instance, scoring="f1_weighted" instead of scoring="f1"
Comment puis-je gérer correctement mes données déséquilibrées afin de calculer correctement les métriques du classificateur?
python
machine-learning
nlp
artificial-intelligence
scikit-learn
nouveau_avec_python
la source
la source
average
paramètre dans le troisième cas?Réponses:
Je pense qu'il y a beaucoup de confusion sur les poids utilisés pour quoi. Je ne suis pas sûr de savoir précisément ce qui vous dérange donc je vais aborder différents sujets, soyez indulgents avec moi;).
Poids de classe
Les poids du
class_weight
paramètre sont utilisés pour entraîner le classificateur . Ils ne sont utilisés dans le calcul d'aucune des métriques que vous utilisez : avec des poids de classe différents, les nombres seront différents simplement parce que le classificateur est différent.Fondamentalement, dans chaque classificateur scikit-learn, les poids de classe sont utilisés pour indiquer à votre modèle l'importance d'une classe. Cela signifie que pendant la formation, le classificateur fera des efforts supplémentaires pour classer correctement les classes avec des poids élevés.
La façon dont ils font cela est spécifique à l'algorithme. Si vous voulez des détails sur la façon dont cela fonctionne pour SVC et que le document n'a pas de sens pour vous, n'hésitez pas à le mentionner.
Les métriques
Une fois que vous avez un classificateur, vous voulez savoir comment il fonctionne. Ici , vous pouvez utiliser les paramètres que vous avez mentionnés:
accuracy
,recall_score
,f1_score
...Habituellement, lorsque la distribution des classes est déséquilibrée, la précision est considérée comme un mauvais choix car elle donne des scores élevés aux modèles qui ne font que prédire la classe la plus fréquente.
Je ne détaillerai pas toutes ces métriques mais noter que, à l'exception de
accuracy
, elles sont naturellement appliquées au niveau de la classe: comme vous pouvez le voir dans ceprint
rapport de classification, elles sont définies pour chaque classe. Ils s'appuient sur des concepts tels quetrue positives
oufalse negative
qui nécessitent de définir quelle classe est la classe positive .L'avertissement
Vous obtenez cet avertissement parce que vous utilisez le score f1, le rappel et la précision sans définir comment ils doivent être calculés! La question pourrait être reformulée: à partir du rapport de classification ci-dessus, comment sortez-vous un nombre global pour le score f1? Vous pourriez:
avg / total
résultat ci-dessus. C'est aussi appelé calcul de la moyenne macro .'weighted'
dans scikit-learn pesera le score f1 par le support de la classe: plus une classe a d'éléments, plus le score f1 pour cette classe est important dans le calcul.Ce sont 3 des options de scikit-learn, l'avertissement est là pour dire que vous devez en choisir une . Vous devez donc spécifier un
average
argument pour la méthode de score.Celui que vous choisissez dépend de la façon dont vous souhaitez mesurer les performances du classificateur: par exemple, le macro-moyennage ne prend pas en compte le déséquilibre de classe et le score f1 de la classe 1 sera tout aussi important que le score f1 de la classe 5. Si vous utilisez la moyenne pondérée, vous aurez plus d'importance pour la classe 5.
Toute la spécification des arguments dans ces métriques n'est pas très claire dans scikit-learn pour le moment, elle s'améliorera dans la version 0.18 selon la documentation. Ils suppriment certains comportements standard non évidents et émettent des avertissements pour que les développeurs le remarquent.
Calcul des scores
La dernière chose que je veux mentionner (n'hésitez pas à l'ignorer si vous en êtes conscient), c'est que les scores ne sont significatifs que s'ils sont calculés sur des données que le classificateur n'a jamais vues . Ceci est extrêmement important car tout score obtenu sur les données utilisées pour ajuster le classificateur est totalement hors de propos.
Voici un moyen de le faire en utilisant
StratifiedShuffleSplit
, qui vous donne un fractionnement aléatoire de vos données (après mélange) qui préserve la distribution des étiquettes.J'espère que cela t'aides.
la source
class_weight={1:10}
donnée qui a 3 classes?ValueError: The least populated class in y has only 1 member, which is too few. The minimum number of labels for any class cannot be less than 2.
. Cela fonctionne bien avec la division train-test, mais quelqu'un peut-il m'aider pourquoi je reçois cette erreur avec SSS? Merci.Beaucoup de réponses très détaillées ici, mais je ne pense pas que vous répondiez aux bonnes questions. Si je comprends bien la question, il y a deux préoccupations:
1.
Vous pouvez utiliser la plupart des fonctions de notation de scikit-learn aussi bien avec des problèmes multiclasses qu'avec des problèmes à classe unique. Ex.:
De cette façon, vous vous retrouvez avec des nombres tangibles et interprétables pour chacune des classes.
Ensuite...
2.
... vous pouvez dire si les données déséquilibrées sont même un problème. Si le score des classes les moins représentées (classes 1 et 2) est inférieur à celui des classes avec plus d'échantillons d'apprentissage (classes 4 et 5), vous savez que les données déséquilibrées sont en fait un problème et vous pouvez agir en conséquence, comme décrit dans certaines des autres réponses de ce fil. Cependant, si la même distribution de classe est présente dans les données que vous souhaitez prédire, vos données d'entraînement déséquilibrées sont un bon représentant des données et, par conséquent, le déséquilibre est une bonne chose.
la source
precision_recall_fscore_support
? Les étiquettes sont-elles imprimées sur commande?average=None
et définissez les étiquettes, puis vous obtenez la métrique que vous recherchez, pour chacune de vos étiquettes spécifiées.Question posée
Pour répondre à la question «quelle métrique utiliser pour la classification multi-classes avec des données déséquilibrées»: Macro-F1-mesure. La précision de macro et le rappel de macro peuvent également être utilisés, mais ils ne sont pas aussi facilement interprétables que pour la classificaion binaire, ils sont déjà incorporés dans la mesure F, et les métriques en excès compliquent la comparaison des méthodes, le réglage des paramètres, etc.
Les micro-moyennes sont sensibles au déséquilibre des classes: si votre méthode, par exemple, fonctionne bien pour les étiquettes les plus courantes et en perturbe totalement les autres, les métriques micro-moyennes donnent de bons résultats.
La moyenne de pondération n'est pas bien adaptée aux données déséquilibrées, car elle pondère par le nombre d'étiquettes. De plus, il est trop difficilement interprétable et impopulaire: par exemple, il n'est pas fait mention d'une telle moyenne dans l' enquête très détaillée suivante que je recommande vivement de parcourir:
Question spécifique à l'application
Cependant, pour revenir à votre tâche, je rechercherais 2 sujets:
Métriques couramment utilisées. Comme je peux le déduire après avoir parcouru la littérature, il existe 2 principales mesures d'évaluation:
( lien ) - notez que les auteurs travaillent avec presque la même répartition des notes, voir la figure 5.
( lien )
( lien ) - ils explorent à la fois la précision et la MSE, considérant que cette dernière est meilleure
( lien ) - ils utilisent scikit-learn pour l'évaluation et les approches de base et déclarent que leur code est disponible; cependant, je ne le trouve pas, donc si vous en avez besoin, écrivez une lettre aux auteurs, le travail est assez récent et semble être écrit en Python.
Coût des différentes erreurs . Si vous vous souciez davantage d'éviter les grossières maladresses, par exemple, donner un avis de 1 étoile à 5 étoiles ou quelque chose du genre, regardez MSE; si la différence compte, mais pas tellement, essayez MAE, car elle ne met pas la différence au carré; sinon restez avec Précision.
À propos des approches, pas des métriques
Essayez des approches de régression, par exemple SVR , car elles surpassent généralement les classificateurs Multiclass comme SVC ou OVA SVM.
la source
Tout d'abord, il est un peu plus difficile d'utiliser simplement une analyse de comptage pour savoir si vos données sont déséquilibrées ou non. Par exemple: 1 observation positive sur 1000 n'est qu'un bruit, une erreur ou une percée scientifique? On ne sait jamais.
Il est donc toujours préférable d'utiliser toutes vos connaissances disponibles et de choisir son statut avec tous les sages.
D'accord, et si c'est vraiment déséquilibré?
Encore une fois, regardez vos données. Parfois, vous pouvez trouver une ou deux observations multipliées par cent. Parfois, il est utile de créer ces fausses observations à une classe.
Si toutes les données sont propres, l'étape suivante consiste à utiliser des pondérations de classe dans le modèle de prédiction.
Alors qu'en est-il des métriques multiclasses?
D'après mon expérience, aucune de vos mesures n'est généralement utilisée. Il y a deux principales raisons.
Premièrement: il est toujours préférable de travailler avec des probabilités qu'avec des prédictions solides (car sinon, comment pourriez-vous séparer les modèles avec une prédiction de 0.9 et 0.6 s'ils vous donnent tous les deux la même classe?)
Et deuxièmement: il est beaucoup plus facile de comparer vos modèles de prédiction et de construire de nouveaux ceux qui dépendent d'une seule bonne métrique.
D'après mon expérience, je pourrais recommander logloss ou MSE (ou simplement dire erreur au carré).
Comment corriger les avertissements sklearn?
Simplement (comme yangjie l'a remarqué) écrasez le
average
paramètre avec l'une de ces valeurs:'micro'
(calculer les métriques globalement),'macro'
(calculer les métriques pour chaque étiquette) ou'weighted'
(comme la macro mais avec des pondérations automatiques).Tous vos avertissements sont venus après l' appel de fonctions métriques par défaut avec la
average
valeur'binary'
qui ne convient pas pour la prédiction multiclassent.Bonne chance et amusez-vous avec l'apprentissage automatique!
Edit:
J'ai trouvé une autre recommandation du répondant pour passer aux approches de régression (par exemple SVR) avec laquelle je ne peux pas être d'accord. Autant que je me souvienne, il n'y a même pas de régression multiclasse. Oui, il existe une régression à étiquettes multiples qui est très différente et oui, il est possible dans certains cas de basculer entre la régression et la classification (si les classes sont triées) mais c'est assez rare.
Ce que je recommanderais (dans le cadre de scikit-learn) est d'essayer un autre outil de classification très puissant: le renforcement du gradient , la forêt aléatoire (mon préféré), KNeighbors et bien d'autres.
Après cela, vous pouvez calculer la moyenne arithmétique ou géométrique entre les prédictions et la plupart du temps, vous obtiendrez un résultat encore meilleur.
la source