Próbuję powielić wyniki z sklearn
biblioteki regresji logistycznej przy użyciu glmnet
pakietu w języku R.
Z dokumentacjisklearn
regresji logistycznej próbuje zminimalizować funkcję kosztu w ramach kary l2
Z winiet z glmnet
jego realizacja minimalizuje nieco inny kosztów funkcji
Z drobnymi poprawkami w drugim równaniu i ustawiając ,
który różni się od sklearn
funkcji kosztu tylko współczynnikiem jeśli jest ustawiony , więc spodziewałem się tego samego oszacowania współczynnika z dwóch pakietów. Ale są różne. Używam zestawu danych z UCLA Idre poradnik , przewidywania admit
na podstawie gre
, gpa
i rank
. Istnieje 400 obserwacji, więc przy , .
#python sklearn
df = pd.read_csv("https://stats.idre.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')
X.head()
> Intercept C(rank)[T.2] C(rank)[T.3] C(rank)[T.4] gre gpa
0 1 0 1 0 380 3.61
1 1 0 1 0 660 3.67
2 1 0 0 0 800 4.00
3 1 0 0 1 640 3.19
4 1 0 0 1 520 2.93
model = LogisticRegression(fit_intercept = False, C = 1)
mdl = model.fit(X, y)
model.coef_
> array([[-1.35417783, -0.71628751, -1.26038726, -1.49762706, 0.00169198,
0.13992661]])
# corresponding to predictors [Intercept, rank_2, rank_3, rank_4, gre, gpa]
> # R glmnet
> df = fread("https://stats.idre.ucla.edu/stat/data/binary.csv")
> X = as.matrix(model.matrix(admit~gre+gpa+as.factor(rank), data=df))[,2:6]
> y = df[, admit]
> mylogit <- glmnet(X, y, family = "binomial", alpha = 0)
> coef(mylogit, s = 0.0025)
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -3.984226893
gre 0.002216795
gpa 0.772048342
as.factor(rank)2 -0.530731081
as.factor(rank)3 -1.164306231
as.factor(rank)4 -1.354160642
Dane R
wyjściowe są w jakiś sposób zbliżone do regresji logistycznej bez regularyzacji, co można zobaczyć tutaj . Czy coś brakuje lub robię coś ewidentnie niewłaściwego?
Aktualizacja: Próbowałem również użyć LiblineaR
pakietu w R
celu przeprowadzenia tego samego procesu, a mimo to otrzymałem inny zestaw szacunków ( liblinear
jest to również solver sklearn
):
> fit = LiblineaR(X, y, type = 0, cost = 1)
> print(fit)
$TypeDetail
[1] "L2-regularized logistic regression primal (L2R_LR)"
$Type
[1] 0
$W
gre gpa as.factor(rank)2 as.factor(rank)3 as.factor(rank)4 Bias
[1,] 0.00113215 7.321421e-06 5.354841e-07 1.353818e-06 9.59564e-07 2.395513e-06
Aktualizacja 2: wyłączenie standaryzacji w glmnet
daje:
> mylogit <- glmnet(X, y, family = "binomial", alpha = 0, standardize = F)
> coef(mylogit, s = 0.0025)
6 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -2.8180677693
gre 0.0034434192
gpa 0.0001882333
as.factor(rank)2 0.0001268816
as.factor(rank)3 -0.0002259491
as.factor(rank)4 -0.0002028832
Odpowiedzi:
regresja logistyczna sklearn domyślnie nie standaryzuje danych wejściowych, co zmienia znaczenie regularyzacji ; prawdopodobnie robi to Glmnet.L.2)
Zwłaszcza, że twój
gre
termin jest na tak większą skalę niż inne zmienne, zmieni to względne koszty użycia różnych zmiennych dla wag.Pamiętaj również, że dołączając do funkcji wyraźny termin przechwytywania, regulujesz przechwytywanie modelu. Zasadniczo tak się nie dzieje, ponieważ oznacza to, że model nie jest już współzmiennym z przesunięciem wszystkich etykiet o stałą.
źródło
glmnet
pozwala wyłączyć standaryzację wejść, ale szacowane współczynniki są jeszcze bardziej różne, patrz wyżej. Ponadto wyraźnie uwzględniłem pojęcie przechwytywania w,sklearn
ponieważglmnet
obejmuje ono jeden automatycznie, aby upewnić się, że dane wejściowe do obu modeli są takie same.X
i przekażfit_intercept=True
(domyślnie) doLogisticRegression
. Prawdopodobnie dzieje się też coś innego.[-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]
dlasklearn
i[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]
dlaglmnet
kolejności[Intercept, rank_2, rank_3, rank_4, gre, gpa]
. Obawiam się, że różnią się one zarówno pod względem wielkości, jak i pozytywnie / negatywnie wpływają na prawdopodobieństwo, więc nie wiedząc, dlaczego się różnią, trudno wybrać taką, która będzie interpretowana. A jeśli jest jakakolwiek szansa na błąd w jednej z implementacji, szczególnie ważne jest, aby wiedzieć, na której polegać.Odpowiedź Dougala jest poprawna, regulujesz przechwytywanie w,
sklearn
ale nie w R. Upewnij się, że używasz,solver='newton-cg'
ponieważ default solver ('liblinear'
) zawsze reguluje przechwycenie.por. https://github.com/scikit-learn/scikit-learn/issues/6595
źródło
solver='newton-cg'
wykonane z wynikówsklearn
istatsmodels
spójne. Wielkie dzięki.Należy również użyć
L1_wt=0
argumentu orazalpha
wfit_regularized()
połączeniu.Ten kod w
statsmodels
:jest równoważne z następującym kodem z
sklearn
:Mam nadzieję, że to pomoże!
źródło