Regressione logistica: Scikit Learn vs Statsmodels


31

Sto cercando di capire perché l'output della regressione logistica di queste due librerie dia risultati diversi.

Sto usando il set di dati da UCLA Idre esercitazione , predicendo admitbasa sulla gre, gpae rank. rankviene trattato come variabile categoriale, quindi viene prima convertito in variabile fittizia con rank_1eliminato. Viene inoltre aggiunta una colonna di intercettazione.

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

L'output da statsmodelsè lo stesso mostrato sul sito Web di Idre, ma non sono sicuro del motivo per cui scikit-learn produce un diverso insieme di coefficienti. Riduce al minimo alcune diverse funzioni di perdita? Esiste una documentazione che attesti l'implementazione?

Risposte:


28

Il tuo indizio per capire questo dovrebbe essere che le stime dei parametri dalla stima di scikit-learning sono uniformemente più piccole di grandezza rispetto alla controparte statsmodels. Questo potrebbe farti credere che scikit-learn applichi una sorta di regolarizzazione dei parametri. Puoi confermarlo leggendo la documentazione di scikit-learn .

Non è possibile disattivare la regolarizzazione in scikit-learn, ma è possibile renderlo inefficace impostando il parametro tuning Csu un numero elevato. Ecco come funziona nel tuo caso:

# 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

Grazie mille per la spiegazione! Con questo risultato regolarizzato, stavo cercando di duplicare il risultato usando il glmnetpacchetto in R, ma non sono riuscito a ottenere lo stesso coefficiente. glmnet ha una funzione di costo leggermente diverso confronto con sklearn , ma anche se ho impostato alpha=0in glmnet(che significa utilizzare solo l2-penalità) e insieme 1/(N*lambda)=C, io ancora non ottenere lo stesso risultato?
hurrikale,

La mia intuizione è che se divido entrambi i termini della funzione di costo in glmnetper lambdae imposto la nuova costante in carattere della probabilità logaritmica, che è 1/(N*lambda)uguale a quella in sklearn, le due funzioni di costo diventano identiche o mi manca qualcosa?
hurrikale,

@hurrikale Fai una nuova domanda e collegala qui, e io darò un'occhiata.
Tchakravarty,

Grazie! Ho pubblicato la domanda qui .
hurrikale,

Penso che il modo migliore per disattivare la regolarizzazione in scikit-learn sia impostando penalty='none'.
Nzbuu,

3

Un'altra differenza è che hai impostato fit_intercept = False, che di fatto è un modello diverso. Puoi vedere che Statmodel include l'intercettazione. Non avere un'intercettazione sicuramente cambia i pesi previsti sulle caratteristiche. Prova quanto segue e vedi come confronta:

model = LogisticRegression(C=1e9)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.