Ich versuche, die Ergebnisse aus der sklearn
logistischen Regressionsbibliothek mit glmnet
package in R zu duplizieren .
Aus der Dokumentation der sklearn
logistischen Regression geht es darum, die Kostenfunktion unter l2 Penalty
Ausgehend von den Vignetten von glmnet
minimiert seine Implementierung eine geringfügig andere Kostenfunktion
Mit ein paar Änderungen in der zweiten Gleichung und durch Setzen von wird
was sich von der sklearn
Kostenfunktion nur um einen Faktor von wenn , also habe ich die gleiche Koeffizientenschätzung von den beiden Paketen erwartet. Aber sie sind unterschiedlich. Ich verwende den Datensatz von der UCLA idre Tutorial , die Vorhersage admit
basiert auf gre
, gpa
und rank
. Es gibt 400 Beobachtungen, also mit , .
#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
Die R
Ausgabe kommt der logistischen Regression ohne Regularisierung in gewisser Weise nahe, wie hier zu sehen ist . Vermisse ich etwas oder mache ich offensichtlich etwas falsch?
Update: Ich habe auch versucht, LiblineaR
package in R
zu verwenden, um denselben Prozess durchzuführen, und habe noch einen anderen Satz von Schätzungen erhalten ( liblinear
ist auch der Löser in 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
Update 2: Deaktivieren der Standardisierung in glmnet
gibt:
> 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
Antworten:
Insbesondere, da Ihr
gre
Begriff so umfangreich ist wie die anderen Variablen, ändern sich dadurch die relativen Kosten für die Verwendung der verschiedenen Variablen für die Gewichtung.Beachten Sie auch, dass Sie durch Einfügen eines expliziten Intercept-Terms in die Features den Intercept des Modells regulieren. Dies wird im Allgemeinen nicht durchgeführt, da dies bedeutet, dass Ihr Modell nicht länger kovariant dafür ist, alle Beschriftungen um eine Konstante zu verschieben.
quelle
glmnet
Ermöglicht das Ausschalten der Standardisierung der Eingänge, aber die geschätzten Koeffizienten sind noch unterschiedlicher, siehe oben. Auch ich explizit eingeschlossen Intercept Begriff insklearn
daglmnet
schließt man automatisch, so dass diese sicher zu machen ist , dass die Eingabe in beiden Modellen gleich ist.X
und übergeben Sie siefit_intercept=True
(Standardeinstellung) anLogisticRegression
. Wahrscheinlich ist aber noch etwas anderes los.[-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]
fürsklearn
und[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]
fürglmnet
in der Reihenfolge von[Intercept, rank_2, rank_3, rank_4, gre, gpa]
. Mein Anliegen ist, dass sie sich sowohl in der Größe als auch in der positiven / negativen Auswirkung auf die Wahrscheinlichkeit unterscheiden. Ohne zu wissen, warum sie sich unterscheiden, ist es schwierig, eine zu wählen, die interpretiert werden soll. Und wenn es zufällig einen Fehler in einer der Implementierungen gibt, ist es besonders wichtig, dass ich weiß, auf welche ich mich verlassen kann.Dougals Antwort ist richtig. Sie regulieren den Achsenabschnitt in,
sklearn
aber nicht in R. Stellen Sie sicher, dass Sie sie verwenden,solver='newton-cg'
da default solver ('liblinear'
) den Achsenabschnitt immer reguliert.Siehe https://github.com/scikit-learn/scikit-learn/issues/6595
quelle
solver='newton-cg'
machte die Ergebnisse aussklearn
undstatsmodels
konsistent. Danke vielmals.Sie sollten auch das
L1_wt=0
Argument zusammen mitalpha
infit_regularized()
call verwenden.Dieser Code in
statsmodels
:entspricht dem folgenden Code von
sklearn
:Ich hoffe es hilft!
quelle