Quelles sont les différences entre la régression Ridge en utilisant glmnet de R et scikit-learn de Python?

11

Je passe par la section LAB §6.6 sur Ridge Regression / Lasso dans le livre 'An Introduction to Statistical Learning with Applications in R' de James, Witten, Hastie, Tibshirani (2013).

Plus précisément, j'essaie d'appliquer le Ridgemodèle scikit-learn au jeu de données «Hitters» du package R «ISLR». J'ai créé le même ensemble de fonctionnalités que celui indiqué dans le code R. Cependant, je ne peux pas me rapprocher des résultats du glmnet()modèle. J'ai sélectionné un paramètre de réglage L2 à comparer. (argument 'alpha' dans scikit-learn).

Python:

regr = Ridge(alpha=11498)
regr.fit(X, y)

http://nbviewer.ipython.org/github/JWarmenhoven/ISL-python/blob/master/Notebooks/Chapter%206.ipynb

R:

Notez que l'argument alpha=0dans glmnet()signifie qu'une pénalité L2 doit être appliquée (régression Ridge). La documentation vous avertit de ne pas entrer une seule valeur pour lambda, mais le résultat est le même que dans ISL, où un vecteur est utilisé.

ridge.mod <- glmnet(x,y,alpha=0,lambda=11498)

Qu'est-ce qui cause les différences?

Edit:
Lors de l'utilisation à penalized()partir du package pénalisé dans R, les coefficients sont les mêmes qu'avec scikit-learn.

ridge.mod2 <- penalized(y,x,lambda2=11498)

Peut-être que la question pourrait alors être aussi: «Quelle est la différence entre glmnet()et penalized()quand faire une régression Ridge?

Nouveau wrapper python pour le code Fortran réel utilisé dans le package R glmnet
https://github.com/civisanalytics/python-glmnet

Jordi
la source
5
Totalement peu familier avec la régression de la crête glmnet. Mais par défaut, sklearn.linear_model.Ridgene fait pas d'estimation d'interception non standardisée (standard) et la pénalité est telle qu'elle ||Xb - y - intercept||^2 + alpha ||b||^2est minimisée pour b. Il peut y avoir des facteurs 1/2ou les 1/n_samplesdeux devant la pénalité, ce qui rend les résultats différents immédiatement. Pour éliminer le problème de mise à l'échelle de la pénalité, définissez la pénalité sur 0 dans les deux cas, résolvez les divergences là-bas, puis vérifiez l'effet de l'ajout de la pénalité. Et à mon humble avis, voici le bon endroit pour poser cette question.

Réponses:

9

Il manque un facteur de ma réponse, veuillez consulter la réponse @visitors ci-dessous pour une comparaison correcte.1N


Voici deux références qui devraient clarifier la relation.

La documentation de sklearn indique que linear_model.Ridgeoptimise la fonction d'objectif suivante

|Xβy|22+α|β|22

Le papier glmnet dit que le filet élastique optimise la fonction objectif suivante

|Xβy|22+λ(12(1α)|β|22+α|β|1)

Notez que les deux implémentations utilisent de manières totalement différentes, sklearn utilise pour le niveau global de régularisation tandis que glmnet utilise à cet effet, réservant pour l'échange entre la régularisation de crête et de lasso. α λ αααλα

En comparant les formules, il semble que la configuration de et dans glmnet devrait récupérer la solution .λ = 2 α sklearnα=0λ=2αsklearnlinear_model.Ridge

Matthew Drury
la source
Et cela m'a totalement manqué dans le commentaire de @eickenberg. Je dois utiliser standardize = FALSEdans glmnet()pour obtenir les mêmes résultats.
Jordi
@Jordi Vous devriez définitivement standardiser si vous utilisez linear_model.Ridgepour toute analyse du monde réel.
Matthew Drury
Je comprends que le linear_model.Ridgemodèle sklearn standardise les fonctionnalités automatiquement. La normalisation est facultative. Je me demande pourquoi je dois ensuite désactiver la normalisation glmnet()pour que les modèles produisent des résultats identiques.
Jordi
10

La réponse de Matthew Drury devrait avoir un facteur 1 / N. Plus précisément...

La documentation de glmnet indique que le filet élastique minimise la fonction de perte

1NXβy22+λ(12(1α)β22+αβ1)

La documentation de sklearn indique que linear_model.Ridgeminimise la fonction de perte

Xβy22+αβ22

ce qui revient à minimiser

1NXβy22+αNβ22

Pour obtenir la même solution de glmnet et sklearn, leurs deux fonctions de perte doivent être égales. Cela signifie définir et dans glmnet.α=0λ=2Nαsklearn

library(glmnet)
X = matrix(c(1, 1, 2, 3, 4, 2, 6, 5, 2, 5, 5, 3), byrow = TRUE, ncol = 3)
y = c(1, 0, 0, 1)
reg = glmnet(X, y, alpha = 0, lambda = 2 / nrow(X))
coef(reg)

sortie glmnet: –0.03862100, –0.03997036, –0.07276511, 0.42727955

import numpy as np
from sklearn.linear_model import Ridge
X = np.array([[1, 1, 2], [3, 4, 2], [6, 5, 2], [5, 5, 3]])
y = np.array([1, 0, 0, 1])
reg = Ridge(alpha = 1, fit_intercept = True, normalize = True)
reg.fit(X, y)
np.hstack((reg.intercept_, reg.coef_))

sortie sklearn: –0.03862178, –0.0399697, –0.07276535, 0.42727921

visiteur
la source
4
Les différentes définitions des paramètres et leur mise à l'échelle utilisées dans différentes bibliothèques sont une source courante de confusion.
AaronDefazio
1
Je ne m'attendrais pas à ce que Gung et moi nous trompions.
Michael R. Chernick
2
Oui, vous vous trompez tous les deux. Vos raisons pour rejeter ma modification montrent clairement que vous n'avez pas vu mon commentaire "Facteur manquant de 1 / N" sur stats.stackexchange.com/review/suggested-edits/139985
visiteur
Votre modification a probablement été rejetée, car elle a changé bien plus que ce que vous prétendez. Si vous souhaitez modifier mon message et ne modifier que le facteur manquant, veuillez le faire, mais modifier mes liens, ma formulation et mon code est également exagéré. Les commentaires sur votre traitement injuste dans votre réponse sont inappropriés et sans rapport avec le contenu de la question, veuillez les supprimer. Votre formulation a également tourmenté ma réponse, ce n'est pas la bonne façon de répondre à une modification refusée. Nous aimerions vos précieuses contributions à notre communauté, mais veuillez vous familiariser avec nos normes avant de nous éviscérer.
Matthew Drury
1
@visitor Désolé si je suis sorti un peu bourru. Je devrais vraiment essayer de communiquer que vous semblez être un bon contributeur potentiel au site, et je veux que vous ayez une bonne expérience. Nous avons des normes sociales, comme tout autre groupe, et vous aurez une meilleure expérience si vous en restez conscient. Je pense toujours que "la réponse de Matthew Drury est fausse" est assez dure, il y a sûrement de meilleures façons de communiquer que ma réponse manque par erreur un facteur de . "La réponse de X est fausse" se lit comme une attaque personnelle. 1N
Matthew Drury