Logistische Regression: Scikit Learn gegen Statsmodels


31

Ich versuche zu verstehen, warum die Ergebnisse der logistischen Regression dieser beiden Bibliotheken unterschiedliche Ergebnisse liefern.

Ich verwende den Datensatz von der UCLA idre Tutorial , die Vorhersage admitbasiert auf gre, gpaund rank. rankwird als kategoriale Variable behandelt, daher wird sie zuerst mit rank_1drop in eine Dummy-Variable konvertiert . Eine Abfangspalte wird ebenfalls hinzugefügt.

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

# Output from scikit-learn
model = LogisticRegression(fit_intercept = False)
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]

# Output from statsmodels
logit = sm.Logit(y, X)
logit.fit().params
> Optimization terminated successfully.
     Current function value: 0.573147
     Iterations 6
Intercept      -3.989979
C(rank)[T.2]   -0.675443
C(rank)[T.3]   -1.340204
C(rank)[T.4]   -1.551464
gre             0.002264
gpa             0.804038
dtype: float64

Die Ausgabe von statsmodelsist dieselbe wie auf der idre-Website, aber ich bin nicht sicher, warum scikit-learn einen anderen Satz von Koeffizienten erzeugt. Minimiert es eine andere Verlustfunktion? Gibt es eine Dokumentation, in der die Implementierung angegeben ist?

Antworten:


28

Ihr Anhaltspunkt, um dies herauszufinden, sollte sein, dass die Parameterschätzungen aus der Schätzung zum Lernen von Scikits gleichmäßig kleiner sind als das Gegenstück zum Statistikmodell. Dies könnte zu der Annahme führen, dass Scikit-Learn eine Art Parameter-Regularisierung anwendet. Sie können dies bestätigen, indem Sie die Dokumentation zu scikit learn lesen .

Es gibt keine Möglichkeit, die Regularisierung in scikit-learn auszuschalten, aber Sie können sie unwirksam machen, indem Sie den Optimierungsparameter Cauf eine große Zahl setzen. So funktioniert das in Ihrem Fall:

# module imports
from patsy import dmatrices
import pandas as pd
from sklearn.linear_model import LogisticRegression
import statsmodels.discrete.discrete_model as sm

# read in the data & create matrices
df = pd.read_csv("http://www.ats.ucla.edu/stat/data/binary.csv")
y, X = dmatrices('admit ~ gre + gpa + C(rank)', df, return_type = 'dataframe')

# sklearn output
model = LogisticRegression(fit_intercept = False, C = 1e9)
mdl = model.fit(X, y)
model.coef_

# sm
logit = sm.Logit(y, X)
logit.fit().params

Vielen Dank für die Erklärung! Mit diesem regulierten Ergebnis habe ich versucht, das Ergebnis mithilfe des glmnetPakets in R zu duplizieren , konnte jedoch nicht den gleichen Koeffizienten erhalten. glmnet hat eine etwas andere Kostenfunktion zu vergleichen sklearn , aber selbst wenn ich gesetzt alpha=0in glmnet(dh nur l2-Strafe verwenden) und Set 1/(N*lambda)=C, ich das gleiche Ergebnis immer noch nicht bekommen?
Hurrikale

Meine Intuition ist, dass, wenn ich beide Terme der Kostenfunktion glmnetdurch teile lambdaund die neue Konstante in der Schriftart der Log-Wahrscheinlichkeit einstelle, die 1/(N*lambda)gleich der in ist sklearn, die beiden Kostenfunktionen identisch werden, oder fehlt mir etwas?
Hurrikale

@hurrikale Stellen Sie eine neue Frage und verlinken Sie sie hier, und ich werde einen Blick darauf werfen.
Tschakravarty

Vielen Dank! Ich habe die Frage hier gepostet .
Hurrikale

Ich denke, der beste Weg, die Regularisierung beim Scikit-Lernen auszuschalten, ist das Setzen penalty='none'.
Nzbuu,

3

Ein weiterer Unterschied ist, dass Sie fit_intercept = False gesetzt haben, was praktisch ein anderes Modell ist. Sie können sehen, dass Statsmodel den Achsenabschnitt enthält. Wenn Sie keinen Achsenabschnitt haben, ändern sich die erwarteten Gewichte für die Features. Probieren Sie Folgendes aus und sehen Sie, wie es verglichen wird:

model = LogisticRegression(C=1e9)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.