Regresi Logistik: Belajar Scikit vs glmnet

15

Saya mencoba untuk menduplikasi hasil dari sklearnperpustakaan regresi logistik menggunakan glmnetpaket di R.

sklearn

minw,c12wTw+Ci=1Nlog(exp(-ysaya(XsayaTw+c))+1)

Dari sketsa dari glmnet, pelaksanaannya meminimalkan biaya yang sedikit berbeda fungsi

minβ,β0-[1Nsaya=1Nysaya(β0+xsayaTβ)-catatan(1+e(β0+xsayaTβ))]+λ[(α-1)||β||22/2+α||β||1]

Dengan beberapa perubahan dalam persamaan kedua, dan dengan mengatur ,α=0

λminβ,β01Nλsaya=1N[-ysaya(β0+xsayaTβ)+catatan(1+e(β0+xsayaTβ))]+||β||22/2

yang berbeda dari sklearnfungsi biaya hanya dengan faktor λ jika set 1Nλ=C , jadi saya mengharapkan estimasi koefisien yang sama dari dua paket. Tetapi mereka berbeda. Saya menggunakan dataset dari tutorial idre UCLA , memprediksi admitberdasarkan gre, gpadan rank. Ada 400 pengamatan, jadi dengan C=1 , λ=0,0025 .

#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

The Routput entah bagaimana dekat dengan regresi logistik tanpa regularisasi, seperti dapat dilihat di sini . Apakah saya melewatkan sesuatu atau melakukan sesuatu yang jelas salah?

Pembaruan: Saya juga mencoba menggunakan LiblineaRpaket Runtuk melakukan proses yang sama, dan belum mendapatkan serangkaian perkiraan lain ( liblinearjuga pemecah masalah 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

Pembaruan 2: mematikan standarisasi dalam glmnetmemberi:

> 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
hurrikale
sumber
Apakah Anda pernah memikirkan hal ini?
Huey

Jawaban:

8

L.2

Terutama karena greistilah Anda berada pada skala yang lebih besar daripada variabel lain, ini akan mengubah biaya relatif menggunakan variabel yang berbeda untuk bobot.

Perhatikan juga bahwa dengan memasukkan istilah intersep eksplisit dalam fitur, Anda mengatur intersep model. Ini umumnya tidak dilakukan, karena itu berarti bahwa model Anda tidak lagi kovarian untuk menggeser semua label dengan konstanta.

Dougal
sumber
glmnetmemungkinkan mematikan standardisasi input, tetapi perkiraan koefisien lebih berbeda, silakan lihat di atas. Juga, saya secara eksplisit memasukkan istilah intersep sklearnkarena glmnettermasuk satu secara otomatis, jadi ini untuk memastikan bahwa input ke kedua model adalah sama.
hurrikale
2
@ Burrikale Saya pikir glmnet mungkin tidak mengatur intersep, tetapi sklearn adalah. Jatuhkan kolom intersep dari Xdan lewati fit_intercept=True(default) ke LogisticRegression. Mungkin ada hal lain yang terjadi juga.
Dougal
Saya mencoba apa yang Anda sarankan dan mendapat set koefisien yang berbeda: [-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]untuk sklearndan [-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]untuk glmneturutan [Intercept, rank_2, rank_3, rank_4, gre, gpa]. Kekhawatiran saya adalah mereka berbeda baik dalam besarnya dan secara positif / negatif mempengaruhi probabilitas, jadi tanpa mengetahui mengapa mereka berbeda, sulit untuk memilih satu untuk ditafsirkan. Dan jika ada kemungkinan bug di salah satu implementasi, sangat penting bahwa saya tahu yang harus diandalkan.
hurrikale
7

Jawaban Dougal benar, Anda mengatur intersep sklearntetapi tidak dalam R. Pastikan Anda menggunakan solver='newton-cg'karena default solver ( 'liblinear') selalu mengatur intersep.

lih https://github.com/scikit-learn/scikit-learn/issues/6595

TomDLT
sumber
Pengaturan solver='newton-cg'membuat hasil dari sklearndan statsmodelskonsisten. Terima kasih banyak.
irene
0

Anda juga harus menggunakan L1_wt=0argumen bersama dengan alphadi fit_regularized()panggilan.

Kode ini di statsmodels:

import statsmodels.api as sm
res = sm.GLM(y, X, family=sm.families.Binomial()).fit_regularized(alpha=1/(y.shape[0]*C), L1_wt=0)

setara dengan kode berikut dari sklearn:

from sklearn import linear_model
clf = linear_model.LogisticRegression(C = C)
clf.fit(X, y)

Semoga ini bisa membantu!

Praup Gupta
sumber