Jakie są różnice między regresją Ridge'a przy użyciu glmnet R i scikit-learn Pythona?

11

Przeglądam sekcję LAB §6.6 na temat regresji grzbietu / Lasso w książce „An Introduction to Statistics Learning with Applications in R” Jamesa, Witten, Hastie, Tibshirani (2013).

Mówiąc dokładniej, próbuję zastosować model scikit-learn Ridgedo zestawu danych „Hitters” z pakietu R „ISLR”. Stworzyłem ten sam zestaw funkcji, jak pokazano w kodzie R. Nie mogę jednak zbliżyć się do wyników z glmnet()modelu. Wybrałem jeden parametr dostrajania L2 do porównania. (argument „alfa” w scikit-learn).

Pyton:

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

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

R:

Zauważ, że argument alpha=0w glmnet()oznacza, że ​​należy zastosować karę L2 (regresja Ridge'a). Dokumentacja ostrzega, aby nie wprowadzać pojedynczej wartości lambda, ale wynik jest taki sam, jak w ISL, gdzie używany jest wektor.

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

Co powoduje różnice?

Edycja:
W przypadku korzystania penalized()z pakietu z karą w R współczynniki są takie same jak w przypadku scikit-learn.

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

Może pytanie może następnie być również: „Jaka jest różnica między glmnet()i penalized()robiąc regresji Ridge?

Nowe opakowanie Pythona dla rzeczywistego kodu Fortran używanego w pakiecie R glmnet
https://github.com/civisanalytics/python-glmnet

Jordi
źródło
5
Zupełnie nieznajomy regresji grzbietu glmnet. Ale domyślnie sklearn.linear_model.Ridgedokonuje się niecentralizowanego oszacowania przechwytywania (standard), a kara jest taka, że ||Xb - y - intercept||^2 + alpha ||b||^2jest minimalizowana b. Przed karą mogą występować czynniki 1/2lub 1/n_samplesoba te czynniki , dzięki czemu wyniki są od razu różne. Aby oddzielić problem skalowania kary, ustaw karę na 0 w obu przypadkach, usuń wszelkie rozbieżności, a następnie sprawdź, co powoduje dodanie kary. A przy okazji tutaj IMHO jest właściwym miejscem do zadawania tego pytania.

Odpowiedzi:

9

W mojej odpowiedzi brakuje współczynnika , proszę zobaczyć odpowiedź @visitors poniżej, aby uzyskać prawidłowe porównanie.1N


Oto dwa odniesienia, które powinny wyjaśnić związek.

Dokumentacja sklearn mówi, że linear_model.Ridgeoptymalizuje następującą funkcję celu

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

Papier glmnet mówi, że elastyczna siatka optymalizuje następującą funkcję celu

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

Zauważ, że dwie implementacje używają na zupełnie różne sposoby, sklearn używa do ogólnego poziomu regularyzacji, podczas gdy glmnet używa do tego celu, rezerwując do handlu między regularyzacją grzbietu i lasso. α λ αααλα

Porównując formuły, wygląda na to, że ustawienie i w glmnet powinno odzyskać rozwiązanie .λ = 2 α sklearnα=0λ=2αsklearnlinear_model.Ridge

Matthew Drury
źródło
I zupełnie tego nie zauważyłem w komentarzu @eickenberg. I trzeba używać standardize = FALSEw glmnet()celu uzyskania identycznych wyników.
Jordi,
@Jordi Powinieneś zdecydowanie wystandaryzować, jeśli używasz linear_model.Ridgedo jakiejkolwiek analizy świata rzeczywistego.
Matthew Drury
Rozumiem, że linear_model.Ridgemodel sklearn automatycznie standaryzuje funkcje. Normalizacja jest opcjonalna. Zastanawiam się, dlaczego muszę dezaktywować standaryzację, glmnet()aby uzyskać identyczne wyniki w modelach.
Jordi,
10

Odpowiedź Matthew Drury powinna mieć współczynnik 1 / N. Dokładniej...

Dokumentacja glmnet stwierdza, że ​​elastyczna siatka minimalizuje funkcję strat

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

Dokumentacja sklearn mówi, że linear_model.Ridgeminimalizuje funkcję strat

Xβy22+αβ22

co jest równoważne z minimalizacją

1NXβy22+αNβ22

Aby uzyskać to samo rozwiązanie z glmnet i sklearn, obie funkcje utraty muszą być takie same. Oznacza to ustawienie i w 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)

Wyjście 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_))

wydajność sklearn: –0,03862178, –0,0399697, –0,07276535, 0,42727921

gość
źródło
4
Różne definicje parametrów i ich skalowanie stosowane w różnych bibliotekach są częstym źródłem nieporozumień.
AaronDefazio
1
Nie spodziewałbym się, że zarówno Gung, jak i ja zrozumiemy to źle.
Michael R. Chernick
2
Tak, oboje źle zrozumieliście. Powody, dla których odrzuciłem moją edycję, wyjaśniają, że oboje nie widzieliście mojego komentarza „Brak współczynnika 1 / N” na stats.stackexchange.com/review/suggested-edits/139985
odwiedzający
Twoja edycja została prawdopodobnie odrzucona, ponieważ zmieniła się znacznie bardziej niż tylko to, co twierdzisz. Jeśli chcesz edytować mój post i zmienić tylko brakujący czynnik, zrób to, ale zmiana moich linków, sformułowań i kodu jest również przesadą. Komentarze dotyczące twojego niesprawiedliwego traktowania w Twojej odpowiedzi są niewłaściwe i niezwiązane z treścią pytania, usuń je. Wasze sformułowania również plagarowały moją odpowiedź, to nie jest właściwy sposób na odpowiedź na odrzuconą edycję. Chcielibyśmy, aby twój cenny wkład w naszą społeczność, ale zapoznaj się z naszymi normami przed wypatroszeniem nas.
Matthew Drury
1
@visitor Przepraszam, jeśli trochę zirytowałem. Naprawdę powinienem po prostu powiedzieć, że wydajesz się być dobrym potencjalnym współpracownikiem witryny i chcę, abyś miał dobre wrażenia. Mamy pewne normy społeczne, tak jak każda inna grupa, i będziesz mieć lepsze doświadczenia, jeśli będziesz o nich świadomy. Nadal uważam, że „odpowiedź Matthew Drury'ego jest błędna” jest dość trudna, z pewnością istnieją lepsze sposoby komunikowania, że ​​w mojej odpowiedzi błędnie brakuje czynnika . „Odpowiedź X jest nieprawidłowa” oznacza osobisty atak. 1N
Matthew Drury