Regresi Logistik: Scikit Learn vs Statsmodels

31

Saya mencoba memahami mengapa output dari regresi logistik kedua perpustakaan ini memberikan hasil yang berbeda.

Saya menggunakan dataset dari tutorial idre UCLA , memprediksi admitberdasarkan gre, gpadan rank. rankdiperlakukan sebagai variabel kategori, jadi pertama-tama dikonversi ke variabel dummy dengan rank_1dijatuhkan. Kolom intersep juga ditambahkan.

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

Keluaran dari statsmodelssama dengan yang ditunjukkan pada situs web idre, tapi saya tidak yakin mengapa scikit-learn menghasilkan set koefisien yang berbeda. Apakah ini meminimalkan beberapa fungsi kerugian yang berbeda? Apakah ada dokumentasi yang menyatakan implementasi?

hurrikale
sumber

Jawaban:

28

Petunjuk Anda untuk mencari tahu ini harus bahwa estimasi parameter dari estimasi scikit-learn secara seragam lebih kecil dalam besarnya daripada rekan statsmodels. Ini mungkin membuat Anda percaya bahwa scikit-learn menerapkan semacam pengaturan parameter. Anda dapat mengkonfirmasi ini dengan membaca dokumentasi scikit-learn .

Tidak ada cara untuk mematikan regularisasi di scikit-learn, tetapi Anda dapat membuatnya tidak efektif dengan mengatur parameter tuning Cke sejumlah besar. Inilah cara kerjanya dalam kasus Anda:

# 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
tchakravarty
sumber
Terima kasih banyak atas penjelasannya! Dengan hasil yang diatur ini, saya mencoba untuk menduplikasi hasilnya menggunakan glmnetpaket dalam R, tetapi tidak bisa mendapatkan koefisien yang sama. glmnet memiliki fungsi biaya yang sedikit berbeda dibandingkan dengan sklearn , tetapi bahkan jika saya set alpha=0in glmnet(artinya hanya menggunakan l2-penalti) dan set 1/(N*lambda)=C, saya masih belum mendapatkan hasil yang sama?
hurrikale
Intuisi saya adalah bahwa jika saya membagi kedua syarat fungsi biaya glmnetdengan lambdadan mengatur konstanta baru dalam font-kemungkinan log, yang 1/(N*lambda)sama dengan di sklearn, dua fungsi biaya menjadi identik, atau apakah saya kehilangan sesuatu?
hurrikale
@urrikale Ajukan pertanyaan baru dan tautkan di sini, dan saya akan memeriksanya.
tchakravarty
Terima kasih! Saya memposting pertanyaan di sini .
hurrikale
Saya pikir cara terbaik untuk mematikan regularisasi di scikit-belajar adalah dengan menetapkan penalty='none'.
Nzbuu
3

Perbedaan lainnya adalah Anda telah menyetel fit_intercept = False, yang secara efektif adalah model yang berbeda. Anda dapat melihat bahwa Statsmodel menyertakan intersep. Tidak memiliki intersepsi tentu saja mengubah bobot yang diharapkan pada fitur. Coba yang berikut dan lihat bagaimana perbandingannya:

model = LogisticRegression(C=1e9)

brian dalessandro
sumber