Scikit-learn: Échec de la convergence liblinéaire partout ?

Créé le 15 juil. 2018  ·  70Commentaires  ·  Source: scikit-learn/scikit-learn

Récemment, nous avons fait rapport liblinear sur les échecs de convergence.
Maintenant, cela est signalé dans de nombreux endroits. Je m'attends à ce que nos utilisateurs commencent à le voir partout. Doit-on changer quelque chose ? C'est bizarre si la plupart des utilisations de LinearSVC entraînent un "échec" maintenant.

High Priority

Commentaire le plus utile

Étant donné que SAG/SAGA conserve les anciens gradients, il fournit une estimation précise du gradient. Je l'utiliserais comme critère d'arrêt. Pour les problèmes régularisés L1, vous ne pouvez pas l'utiliser, car le gradient n'est plus nul à l'optimum, mais le mappage de gradient peut être utilisé à la place, qui est (1/step_size)(x - prox(x - step_size * grad_estimate))

Tous les 70 commentaires

De plus, il est assez étrange que SVC ait max_iter=-1 et LinearSVC ait max_iter=1000 . Y at-il une raison à cela?

bonne question. En regardant le code liblinear, il semble que nous n'exposons pas les différents critères d'arrêt dont ils disposent et nous avons ajouté un paramètre max_iter qu'ils ne semblent pas avoir.

Je n'ai aucune idée pourquoi il a été fixé à 1000. Y a-t-il eu un benchmark fait ?

Pas que je m'en souvienne...

Pas d'avis bien arrêté. Trop d'avertissements signifie que les utilisateurs ne regardent pas les avertissements.

La seule chose que je puisse suggérer est d'ajouter une option pour contrôler ce comportement. Je n'aime pas trop ajouter des options (le danger est d'en avoir trop), mais il semble ici qu'il n'y ait pas de choix unique.

nous pourrions également augmenter le tol? @ogrisel a demandé si nous avions également cet avertissement pour la régression logistique ou si nous l'ignorons ici.

Ce problème se produit-il également avec la classe LogisticRegression ?

Je suis -1 en augmentant le tol : cela signifiera que de nombreux utilisateurs attendront plus longtemps.

Je pense qu'il devrait y avoir une option pour contrôler les avertissements de convergence.

augmenter le tol signifiant un plus grand tol. Donc, si quoi que ce soit, les gens attendront moins longtemps.

augmenter le tol signifiant un plus grand tol. Donc, si quoi que ce soit, les gens attendront moins longtemps.

OK, je t'avais mal compris.

+1 pour cette option.

Travailler là-dessus.

@ogrisel en effet LogisticRegression est également potentiellement affecté.

Comme discuté avec @agramfort, je suis un peu sceptique quant à la suppression du tol car il existe de nombreuses valeurs par défaut différentes :

  • Régression logistique : max_iter=100, tol=0,0001
  • LinearSV{C,R} : max_iter=1000, tol=0.0001
  • SV{C,R} : max_iter=-1, tol=0.001

Il ne s'agit que de liblinear, donc là où le tol est de 0,0001 en ce moment. Ce serait donc plus cohérent. Nous devrions probablement exécuter quelques benchmarks, cependant?

Ah en effet, alors peut-être que ce n'est pas aussi complexe que je le pensais au départ.
Le tol doit-il être de 0,001 par défaut pour tous ces appels liblinear ?
Je suis d'accord pour les benchmarks !

@samronsin ouais ce serait bien je pense. Cela semble l'un des derniers bloqueurs de version?

d'ailleurs le changement qui a provoqué tout cela est #10881 qui n'était fondamentalement qu'un changement de verbosité :-/

btw en utilisant le solveur par défaut, tol est de 0,1 (!) dans liblinear par défaut. https://github.com/cjlin1/liblinear/blob/master/README

Wow. Que de belles surprises dans Liblinear...​

@jnothman c'est surtout notre wrapper qui a les surprises, je pense ?

tbh je ne l'ai pas regardé...

La ligne de commande liblinear a en fait plusieurs valeurs par défaut de tolérance , selon le sous-solveur utilisé.

Voulons-nous les utiliser ? Cela nécessiterait probablement de changer la valeur par défaut en 'auto' .

Je veux que nous y réfléchissions après la sortie :)

Je pense que différentes tolérances par défaut (et itérations) basées sur le solveur ont du sens en général ! Il semble y avoir un consensus ici sur l'augmentation de la tolérance liblinéaire.

Devrions-nous donc en faire la même chose que dans liblinear ? Ou comment choisiriez-vous de nouvelles valeurs par défaut ? Avec cycle de dépréciation ?

Le cycle de dépréciation ici est une nuisance... Pouvons-nous l'appeler une correction de bogue ???
L'utilisation des valeurs par défaut liblinear a l'avantage de ne pas avoir besoin de justifier les nôtres !

Je suis d'accord avec les deux ;)

Résolution de la réunion au sprint :

  • Modifiez le max_iter et le tol pour qu'ils soient spécifiques au solveur, la raison en est qu'une "itération" signifie quelque chose pour différents solveurs, ainsi que pour tol. L'idée serait de définir tol et max_iter sur "auto" par défaut par défaut et de basculer en fonction des paramètres.

Les choix nécessitent des repères (le PR ajoutant sag ou saga en avait probablement un, il se trouve peut-être dans le dossier des repères).

Très probablement, nous utiliserons max_iter égal à 100 et 1000 (par exemple 100 pour les méthodes quasi-Newton et 1000 pour les solveurs de premier ordre / descente de coordonnées).

Répartition des travaux :

  • [ ] Enquêter sur la modification du type de tol de lbfgs en ftol plutôt que pgtol
  • [ ] Étudiez quelle valeur de tol conduit à une bonne prédiction sur différentes données et avec différents solveurs (pour liblinear, nous devrions étudier les valeurs par défaut de liblinear)
  • [ ] Recherchez quelle valeur de max_iter conduit le plus souvent à converger vers le tol ci-dessus

L'autre chose à noter ici est qu'à un moment donné, nous avons exposé max_iter dans liblinear (après l'ajout d'autres solveurs) et avons ainsi changé le nombre d'itérations par défaut de 1000 à 100 sans en informer les utilisateurs.

Nous sommes disposés à modifier les valeurs par défaut ici en tant que correctif de bogue, sans maintenir la rétrocompatibilité, si cela fournit des taux de convergence plus raisonnables.

( @GaelVaroquaux est quelqu'un qui y est affecté, ou devrions-nous l'étiqueter Aide recherchée ?)

@FollowKenny : J'ai pensé que vous pourriez avoir le temps avec ça (une fois que vous avez fini d'optimiser deux lignes de code).

Je commence à travailler là-dessus car je ne pouvais pas comprendre ce qui n'allait pas avec ces 2 lignes...

d'ailleurs, ce que je viens de réaliser, c'est qu'avec les paramètres actuels, il est assez difficile de faire converger la régression logistique vers mnist en un temps fini sans jouer avec tol et max_iter... pour aucun des solveurs. Ce n'est pas si génial.

(par converger je veux dire arrêter le montage)

Notez que sur les plates-formes Windows, liblinear est connu pour avoir de forts problèmes de convergence en raison de la façon dont les nombres aléatoires sont générés : le nombre aléatoire maximum dans Windows est de 15 bits (même sur les fenêtres 64 bits), soit 32767, tandis que le nombre aléatoire maximum dans Linux+ GCC est de 31 bits (resp. 63 bits dans les systèmes 64 bits je suppose) donc c'est 2147483647 (resp 9223372036854775807).

Il s'agit d'un bogue connu documenté dans la FAQ liblinear mais la solution de contournement proposée était erronée - j'ai fait un correctif pour cela il y a des années, qui a été approuvé par plusieurs utilisateurs mais n'a jamais fusionné : https://github.com/cjlin1/liblinear/pull/28 .

Désolé de sonner ici tard, mais avec tous mes workflows existants où j'utilise LinearSVC(), j'ai commencé à avoir des échecs de convergence Liblinear partout avec 0.20.x où exactement le même code fonctionne parfaitement dans 0.19.x. Je n'ai jamais reçu d'avertissements de convergence avec 0.19.x. Qu'est ce qui a changé?

(en plus de mon message ci-dessus) J'utilise actuellement libsvm et liblinear sur un autre projet et le bogue de convergence signalé ci-dessus pour les plates-formes Windows semble également être présent dans libsvm. Un autre utilisateur l'a signalé .

J'ai vu que les sources originales sont en fait copiées dans scikit-learn. Je vais donc proposer une pull request.
En parallèle j'essaierai de motiver le(s) auteur(s) en faisant un lien vers ce post et PR.
Tous les commentaires/réflexions/idées sont les bienvenus :)

Je peux me tromper, mais je pense que nous n'avions pas signalé
ConvergenceWarnings en liblinear jusqu'à 0.20. Obtenez-vous le même ajustement
en 0,19 et 0,20, @hermidalc?

Je peux me tromper, mais je pense que nous n'avions pas signalé les ConvergenceWarnings dans liblinear jusqu'à 0.20. Obtenez-vous le même ajustement en 0,19 et 0,20, @hermidalc ?

Oh, je ne le savais pas, je vais vérifier avec quelques ensembles de données pour voir et faire rapport

Devrions-nous corriger le réglage de liblinear max_iter à ce qu'il était avant de créer max_iter dans LogisticRegression ??

d'ailleurs, ce que je viens de réaliser, c'est qu'avec les paramètres actuels, il est assez difficile de faire converger la régression logistique vers mnist en un temps fini sans jouer avec tol et max_iter... pour aucun des solveurs. Ce n'est pas si génial.

En effet et apparemment cela dépend vraiment aussi du solveur :

  • pour SAG / SAGA, le critère d'arrêt est basé sur la valeur absolue maximale des variations des coefficients et en effet avec la régularisation par défaut il ne s'est pas arrêté après plusieurs milliers d'itérations sur MNIST : la max_change ne semble pas monotone diminuer au fil des itérations (comme surveillé avec verbose=1). J'ai dû tuer mon programme python pour qu'il s'arrête. ctrl-c ne fonctionne même pas parce que c'est dans une boucle Cython pure (mais c'est un problème différent).

  • pour l-BFGS, il existe plusieurs critères d'arrêt , basés sur la norme du gradient (contrôlé par pgtol ) et un basé sur le changement en valeur objectif (contrôlé par factr ). Lors de l'exécution de LogisticRegression sur MNIST avec verbose=1, j'ai observé que les boucles s'arrêtaient après quelques dizaines ou centaines d'itérations (selon la régularisation) toujours à cause du critère d'arrêt basé sur les objectifs. Lors de la modification du paramètre tol dans scikit-learn, on modifie le paramètre pgtol de l-BFGS qui n'a aucun effet sur le paramètre factr et le critère d'arrêt basé sur les objectifs. Il faut augmenter beaucoup tol (par exemple 1e-1 ou 1e-2) pour que le critère d'arrêt basé sur la pente s'arrête en premier.

Pour référence, voici la signification exacte des deux paramètres d'arrêt l-BFGS :

factr : float, optional

    The iteration stops when (f^k - f^{k+1})/max{|f^k|,|f^{k+1}|,1} <= factr * eps, where eps is
     the machine precision, which is automatically generated by the code. Typical values for
     factr are: 1e12 for low accuracy; 1e7 for moderate accuracy; 10.0 for extremely high
     accuracy. See Notes for relationship to ftol, which is exposed (instead of factr) by the
     scipy.optimize.minimize interface to L-BFGS-B.

pgtol : float, optional

    The iteration will stop when max{|proj g_i | i = 1, ..., n} <= pgtol where pg_i is the i-th
     component of the projected gradient.
  • pour newton-cg : seule la norme du gradient semble servir de critère d'arrêt . Je n'ai pas encore mené d'expériences approfondies sur mnist avec ce solveur pour vérifier si l'absence de critère d'arrêt basé sur des objectifs peut causer des problèmes.

@TomDLT @fabianp @arthurmensch savez-vous si c'est une bonne pratique de ne compter que sur le changement de paramètre comme critère d'arrêt pour SAG / SAGA ? Pour les modèles de régression logistique faiblement régularisés, cela semble être problématique. Nous pourrions vouloir ajouter un deuxième critère d'arrêt basé sur la fonction objectif comme dans l-BFGS. Le problème est que nous ne voulons pas ré-analyser l'ensemble de données complet à la fin d'une époque juste pour calculer la valeur objective. On pourrait accumuler une moyenne retardée des valeurs de perte de mini-lots et comparer à la fin de chaque époque cette moyenne retardée à sa valeur d'époque précédente, mais cela n'est plus exactement lié à la valeur objective exacte de fin d'époque. Je ne connais pas assez la théorie de la convergence SAG et SAGA pour savoir si ce que je propose a du sens ou non.

Deuxième question : plus généralement, devons-nous modifier le paramètre tol impacter le critère d'arrêt basé sur la valeur objective pour tous les solveurs de manière cohérente ? Je crois que oui, mais alors comment faire un compromis avec le critère d'arrêt basé sur le changement de paramètre ? Doit-on introduire un deuxième paramètre de tolérance ?

Étant donné que SAG/SAGA conserve les anciens gradients, il fournit une estimation précise du gradient. Je l'utiliserais comme critère d'arrêt. Pour les problèmes régularisés L1, vous ne pouvez pas l'utiliser, car le gradient n'est plus nul à l'optimum, mais le mappage de gradient peut être utilisé à la place, qui est (1/step_size)(x - prox(x - step_size * grad_estimate))

Merci, ça a l'air d'être une bonne suggestion. Est-ce la stratégie que vous utilisez dans vos propres implémentations de SAGA ? Combinez-vous cela avec un deuxième critère basé sur un changement de perte moyenne retardé entre deux itérations ? Ou peut-être que la stochasticité dans l'ordre des échantillons qui changent au fil des itérations est susceptible d'amener le solveur à s'arrêter trop tôt avec un critère d'arrêt naïf basé sur de telles approximations de la valeur objective.

Je ne le fais pas (mais devrais).

Je peux me tromper, mais je pense que nous n'avions pas signalé les ConvergenceWarnings dans liblinear jusqu'à 0.20. Obtenez-vous le même ajustement en 0,19 et 0,20, @hermidalc ?

Salut @jnothman et al et désolé pour le retard. Je l'ai vérifié maintenant sur 0,20 et 0,21 et oui, j'obtiens les mêmes ajustements que pour 0,19. Je peux également confirmer que lorsque j'utilise SVC avec kernel=linear, j'obtiens des ajustements similaires.

Ce qui est également étrange, c'est que même si je définis LinearSVC max_iter=5000, il ne parvient toujours pas à converger avec tous les avertissements, même sur des problèmes qui ont de très bons ajustements (par exemple, ROC AUC >= 0.85)

avons-nous / devrions-nous avoir un problème de régression logistique pour définir correctement les tolérances ?

13317 est un pr

J'ai essayé pour l'instant de supprimer les avertissements de convergence Liblinear, mais je constate que lors de l'exécution de GridSearchCV le backend joblib loky par défaut ignore les paramètres filterwarnings :

warnings.filterwarnings("ignore", category=ConvergenceWarning, message="^Liblinear failed to converge")

Avec le backend de multitraitement joblib, cela fonctionne et supprime ces avertissements des processus de travail.

Est-ce que quelqu'un sait comment faire pour que les paramètres filterwarnings se propagent aux processus de travail Loky ?

De plus, tout le monde recommande-t-il Loky plutôt que le multiprocessus pour la plupart des workflows scikit-learn ? Ils ont chacun leurs avantages/inconvénients.

Je vois maintenant que ce problème avec Loky et filterwarnings est discuté dans le problème #12939.

Bien que vous aimeriez toujours savoir si le backend Loky ou multiprocessing est recommandé pour la plupart des workflows sklearn ?

Je ne pense pas que ces avertissements doivent être filtrés, nous devrions trouver une meilleure tolérance par défaut.

Ok donc c'est pas mal :

from sklearn.datasets import load_digits
from sklearn.svm import LinearSVC
digits = load_digits()
svm = LinearSVC(tol=1, max_iter=10000)
svm.fit(digits.data, digits.target)

Si les données ne sont pas mises à l'échelle, le solveur double (qui est la valeur par défaut) ne convergera jamais vers le jeu de données digits.

Cela ne peut pas vraiment être résolu avec tol et max_iter, je pense :(

Avons-nous mis en garde contre la mise à l'échelle dans SVR ?

Je ne pense pas que nous mettions en garde contre la mise à l'échelle n'importe où?
De plus, il s'agit d'un modèle linéaire. Il devrait vraiment converger sans mise à l'échelle.

Alors, pensez-vous que dual devrait être False par défaut dans LinearSVC ?

@jnothman Je pense que nous devons comparer mais peut-être?

Je ne pense pas que nous mettions en garde contre la mise à l'échelle n'importe où?
De plus, il s'agit d'un modèle linéaire. Il devrait vraiment converger sans mise à l'échelle.

SVC(kernel='linear') c'est- max_iter=-1 ) pour de nombreux ensembles de données que j'ai si vous ne redimensionnez pas les données auparavant. Je ne suis donc pas d'accord ici... si vous avez des caractéristiques avec des échelles très différentes des autres, il deviendra difficile d'adapter l'hyperplan optimal à une tolérance raisonnable.

Ok donc c'est pas mal :

from sklearn.datasets import load_digits
from sklearn.svm import LinearSVC
digits = load_digits()
svm = LinearSVC(tol=1, max_iter=10000)
svm.fit(digits.data, digits.target)

Si les données ne sont pas mises à l'échelle, le solveur double (qui est la valeur par défaut) ne convergera jamais vers le jeu de données digits.

Cela ne peut pas vraiment être résolu avec tol et max_iter, je pense :(

Partout dans les vous mettre en garde spécifiquement docs sklearn utilisateurs qu'ils ont besoin de données à grande échelle avant de l' utiliser avec beaucoup de classificateurs, etc. Si un des ensembles tol et max_iter aux valeurs par défaut correctes pour liblinear solveur double L2 pénalisée alors digits converge :

from sklearn.datasets import load_digits
from sklearn.svm import LinearSVC
digits = load_digits()
p = Pipeline([('s', StandardScaler()),
              ('c', LinearSVC(tol=1e-1, max_iter=1000))])
p.fit(digits.data, digits.target)

@hermidalc juste pour être sûr, utilisez-vous Windows ou un Unix ? En effet, il existe un problème connu avec Windows (#13511 ) - mais cela ne se produit que lorsque le nombre de fonctionnalités ou d'échantillons est très important, donc je suppose que ce n'est pas le problème auquel vous êtes confronté.

@hermidalc juste pour être sûr, utilisez-vous Windows ou un Unix ? En effet, il existe un problème connu avec Windows (#13511 ) - mais cela ne se produit que lorsque le nombre de fonctionnalités ou d'échantillons est très important, donc je suppose que ce n'est pas le problème auquel vous êtes confronté.

Linux. Le seul problème auquel j'ai été confronté concerne les avertissements de convergence LinearSVC car le tol=1e-4 par défaut dans sklearn n'est pas ce que les états liblinear devraient être le 1e-1 par défaut pour le double solveur L2 par défaut. Lorsque vous définissez tol=1e-1 et normalisez vos données auparavant (ce qui est un must pour SVM et de nombreux autres classificateurs), ces problèmes de convergence disparaissent.

Vous ne voulez pas ajouter plus au pot... mais l'avertissement de convergence est-il également spécifique au système d'exploitation car il devrait se comporter différemment sur chaque système d'exploitation ? J'ai supposé que non, mais d'après mes découvertes, cela semble être le cas. J'ai testé sur macOS 10.15.2 (Catalina) vs Linux Fedora 30.

J'ai exécuté le code instantané de -> https://github.com/scikit-learn/scikit-learn/issues/11536#issuecomment -529637160 par @amueller et comme vous pouvez le voir ci-dessous pour macOS cette erreur ne s'affiche pas, mais sur Linux, il affiche cette erreur (même code !!!). Je ne suis pas sûr du pourquoi ? Est-ce parce qu'il peut y avoir des versions différentes de liblinear sur mac que sur Linux ?

Testé dans les deux versions majeures de python avec des bibliothèques anciennes et récentes et les résultats étaient les mêmes.

  • macos -> py2.7 avec les bibliothèques numpy==1.16.3 scikit-learn==0.20.3 scipy==1.2.1
  • fedora -> py2.7 avec les bibliothèques numpy==1.16.3 scikit-learn==0.20.3 scipy==1.2.1
  • fedora -> py3.7 avec les bibliothèques numpy==1.17.4 scikit-learn==0.22 scipy==1.3.3

résultat mac

python test/svc.py
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=10000,
     multi_class='ovr', penalty='l2', random_state=None, tol=1, verbose=0)

résultat du feutre

python /vagrant/test/svc.py
/home/vagrant/.local/lib/python2.7/site-packages/sklearn/svm/base.py:931: ConvergenceWarning: Liblinear failed to converge, increase the number of iterations.
  "the number of iterations.", ConvergenceWarning)
LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True,
     intercept_scaling=1, loss='squared_hinge', max_iter=10000,
     multi_class='ovr', penalty='l2', random_state=None, tol=1, verbose=0)

Des pensées?

si vous avez des caractéristiques avec des échelles très différentes des autres, il sera difficile d'ajuster l'hyperplan optimal à une tolérance raisonnable.

Cela dépend un peu de ce que vous entendez par "difficile". Vous pourriez probablement faire quelque chose comme #15583 et résoudre assez bien le problème d'optimisation d'origine. Je ne dis pas que c'est une bonne idée de ne pas mettre à l'échelle vos données, je dis juste qu'il est tout à fait possible de bien résoudre le problème d'optimisation malgré que l'utilisateur vous donne des données mal mises à l'échelle si votre algorithme d'optimisation est suffisamment robuste.

si vous avez des caractéristiques avec des échelles très différentes des autres, il sera difficile d'ajuster l'hyperplan optimal à une tolérance raisonnable.

Cela dépend un peu de ce que vous entendez par "difficile".

Désolé, ce que j'impliquais par difficile est pertinent pour le sujet de ce fil, c'est-à-dire résoudre le problème d'optimisation en dessous d'une tolérance spécifique à ou avant un nombre maximum d'itérations. Les fonctionnalités qui ne sont pas mises à l'échelle rendent cela plus difficile à faire avec SVM à moins, comme vous l'avez dit, d'utiliser un algorithme très robuste pour résoudre le problème d'optimisation. Je pensais que LIBLINEAR utilisait la descente de coordonnées, n'est-ce pas assez robuste ?

oui, la descente des coordonnées est assez robuste à la mise à l'échelle des données.

>

Liblinear a plusieurs solveurs. Je pense qu'ils utilisent leur propre TRON (trust region newton) par défaut.

Aussi: nous venons de changer notre valeur par défaut loin de liblinear...

La question de savoir quels types de problèmes sont "difficiles" dépendra probablement du solveur, je pense, ou de la façon dont vous formulez le problème.

Aussi: nous venons de changer notre valeur par défaut loin de liblinear...

@amueller pouvez-vous m'indiquer le problème/pr correspondant ? Je n'ai pas vu cela dans la base de code principale. Merci!

Ah ok j'ai pensé à tort qu'il s'agissait de SVC. Merci!

si vous avez des caractéristiques avec des échelles très différentes des autres, il sera difficile d'ajuster l'hyperplan optimal à une tolérance raisonnable.

Cela dépend un peu de ce que vous entendez par "difficile". Vous pourriez probablement faire quelque chose comme #15583 et résoudre assez bien le problème d'optimisation d'origine. Je ne dis pas que c'est une bonne idée de ne pas mettre à l'échelle vos données, je dis juste qu'il est tout à fait possible de bien résoudre le problème d'optimisation malgré que l'utilisateur vous donne des données mal mises à l'échelle si votre algorithme d'optimisation est suffisamment robuste.

Pour y revenir, voici quelques preuves supplémentaires qui remettent en question cette croyance en ce qui concerne l'utilisation pratique :

Des créateurs de LIBSVM et LIBLINEAR :
https://www.csie.ntu.edu.tw/~cjlin/papers/guide/guide.pdf

Section 2.2 Mise à l'échelle
La mise à l'échelle avant d'appliquer SVM est très importante. La partie 2 de la FAQ sur les réseaux de neurones de Sarle Sarle (1997) explique l'importance de cela et la plupart des considérations s'appliquent également à la SVM. Le principal avantage de la mise à l'échelle est d'éviter que les attributs des plages numériques plus grandes ne dominent ceux des plages numériques plus petites. Un autre avantage est d'éviter les difficultés numériques lors du calcul. Étant donné que les valeurs du noyau dépendent généralement des produits internes des vecteurs de caractéristiques, par exemple le noyau linéaire et le noyau polynomial, des valeurs d'attribut élevées peuvent causer des problèmes numériques. Nous vous recommandons de mettre à l'échelle linéairement chaque attribut dans la plage [−1, +1] ou [0, 1].
Bien sûr, nous devons utiliser la même méthode pour mettre à l'échelle les données d'entraînement et de test. Par exemple, supposons que nous ayons mis à l'échelle le premier attribut des données d'apprentissage de [−10, +10] à [−1, +1]. Si le premier attribut des données de test se situe dans la plage [−11, +8], nous devons mettre les données de test à l'échelle à [−1.1, +0.8]. Voir l'annexe B pour quelques exemples réels.

@hermidalc J'ai observé qu'il était un peu plus stable que lbfgs dans certains paramètres que j'ai essayés, voir le problème de préconditionnement et pr.

Je ne sais pas exactement comment nous pouvons améliorer l'expérience utilisateur ici :-/ J'ai vu beaucoup de problèmes de convergence même après la mise à l'échelle, mais je n'ai pas eu le temps de les composer.

J'essaie de supprimer les problèmes qui existent depuis plus de 2 versions des jalons. Mais celui-ci semble pressant et vous vous en souciez vraiment @amueller . Le laisser dans le jalon de 0,24, mais nous devrions vraiment être meilleurs dans le suivi de ceux-ci.

@hermidalc J'ai observé qu'il était un peu plus stable que lbfgs dans certains paramètres que j'ai essayés, voir le problème de préconditionnement et pr.

Je ne sais pas exactement comment nous pouvons améliorer l'expérience utilisateur ici :-/ J'ai vu beaucoup de problèmes de convergence même après la mise à l'échelle, mais je n'ai pas eu le temps de les composer.

Je dois dire @amueller que je suis plus d'accord avec toi maintenant. Avec divers ensembles de données de grande dimension avec lesquels j'ai travaillé ces derniers mois, j'ai constaté des problèmes de convergence fréquents avec LinearSVC après avoir correctement transformé et mis à l'échelle les données au préalable, même après avoir défini le tol=1e-1 qui est ce que LIBLINEAR a et paramètre max_iter=10000 ou plus. L'algorithme d'optimisation semble avoir particulièrement des problèmes de convergence lors de la sélection de modèles sur une plage de C lorsque des valeurs plus élevées comme 1e2 ou plus

Les mêmes workflows avec SVC(kernel='linear') n'ont généralement pas de problèmes de convergence. Bien que les scores des deux modèles soient généralement assez similaires, même avec LinearSVC ne pouvant pas converger, ils ne sont pas les mêmes et pour certains ensembles de données, c'est vraiment différent. Donc, pour la classification linéaire pénalisée par L2 où j'utilisais auparavant LinearSVC je reviens maintenant à SVC et SGDClassifier .

Le problème est que seul LinearSVC peut résoudre les problèmes de penalty='l1' et dual=False pour par exemple SelectFromModel sélection de fonctionnalités, il serait donc important que scikit-learn corrige le problème avec la mise en œuvre. Peut-être que SGDClassifier avec penalty='l1' peut être utilisé à la place ?

Peut-être que le dernier code LIBLINEAR a des mises à jour/correctifs qui ont corrigé quel est le problème sous-jacent ? On dirait que le code liblinear principal de sklearn date de 2014.

Cette page vous a été utile?
0 / 5 - 0 notes