LogisticRegression avec GridSearchCV ne convergeant pas

Oct 05 2020

J'essaye de trouver les meilleurs paramètres pour une régression logistoïque mais je trouve que le "meilleur estimateur" ne converge pas.

Existe-t-il un moyen de préciser que l'estimateur doit converger pour en tenir compte?

Voici mon code.

# NO PCA
cv = GroupKFold(n_splits=10)
pipe = Pipeline([('scale', StandardScaler()),
    ('mnl', LogisticRegression(fit_intercept=True, multi_class="multinomial"))])

param_grid = [{'mnl__solver': ['newton-cg', 'lbfgs','sag', 'saga'],
               'mnl__C':[0.5,1,1.5,2,2.5],
               'mnl__class_weight':[None,'balanced'],
              'mnl__max_iter':[1000,2000,3000],
              'mnl__penalty':['l1','l2']}]

grid = GridSearchCV(estimator = pipe, param_grid=param_grid, scoring=scoring, n_jobs=-1, refit='neg_log_loss', cv=cv, verbose=2, return_train_score=True)

grid.fit(X, y, groups=data.groups)


# WITH PCA
pipe = Pipeline([(
    ('scale', StandardScaler()),
    ('pca', PCA())
    ('mnl', mnl)])

param_grid = [{'pca__n_components':[None,15,30,45,65]
            'mnl__solver': ['newton-cg', 'lbfgs','sag', 'saga'],
              'mnl__max_iter':[1000,2000,3000],
             'mnl__C':[0.5,1,1.5,2,2.5],
              'mnl__class_weight':[None,'balanced'],
              'mnl__penalty':['l1','l2']}]

grid = GridSearchCV(estimator = pipe, param_grid=param_grid, scoring='neg_log_loss', n_jobs=-1, refit=True, cv=cv, verbose=2)

grid.fit(X, y, groups=data.groups)

Dans le premier cas, le meilleur estimateur trouvé est avec un solveur l2-lbfgs, avec 1000 itérations, et il converge. Le second, le meilleur estimateur trouvé, est avec le solveur de saga et la pénalité l1, 3000 itérations. Je pense que cela a à voir avec le solveur ... mais de toute façon, y a-t-il un moyen simple de déclarer qu'il doit converger pour l'accepter au mieux?

Réponses

2 BenReiniger Oct 05 2020 at 09:17

Je ne conseillerais pas de faire cette contrainte. L'échec du solveur à converger signifie simplement qu'il n'a pas atteint l'optimum global * dans la tolérance spécifiée . Si vous obtenez de meilleurs scores de validation croisée, vous devriez probablement être "suffisamment proche" de cet optimum pour ne pas vous en préoccuper. Augmentez max_iterpour le radoub, si vous le souhaitez.
* (Dans la régression logistique, la perte est convexe, il n'y a donc qu'un seul optimum global, à l'exception des caractéristiques colinéaires ou de la séparation parfaite.)

Dans un esprit similaire, je ne chercherais pas sur les solveurs (sauf peut-être comme moyen pratique de traiter différents solveurs capables d'utiliser différentes pénalités de régularisation), ou sur le nombre maximum d'itérations. Après avoir corrigé le type de régularisation et la force, il existe des coefficients optimaux uniques (encore une fois, à l'exception des cas dégénérés), et l'exécution de différents solveurs devrait produire les mêmes résultats à moins que (1) le solveur ne déraille d'une manière ou une autre, ou (2) une différence de précision provoque différence. Et le nombre d'itérations devrait juste être réglé assez haut pour atteindre la convergence (notez que c'est le nombre "maximum" d'itérations; si un solveur entre dans sa tolérance avant cela, il ne continuera pas à chugging).

skeerp Oct 05 2020 at 07:26

Il s'agit plus que probablement d'un problème avec vos données ne convenant pas à cette approche, plutôt que votre code étant incorrect. Surtout que vous ne construisez pas votre propre argent ou quoi que ce soit, je vérifierais vraiment vos données plus en détail.