Lojistik Regresyon: Scikit Learn vs glmnet


15

R'deki paketi sklearnkullanarak lojistik regresyon kütüphanesinden sonuçları çoğaltmaya çalışıyorum.glmnet

Kaynaktan sklearnlojistik regresyon belgeleri , bu l2 cezası altında maliyet fonksiyonunu en çalışıyor

minw,c12wTw+Ci=1Nlog(exp(yi(XiTw+c))+1)

Kaynaktan vignettes arasında glmnet, uygulanması biraz daha farklı bir maliyet fonksiyonu minimize

minβ,β0[1Ni=1Nyi(β0+xiTβ)log(1+e(β0+xiTβ))]+λ[(α1)||β||22/2+α||β||1]

İkinci denklemde biraz değişiklik yaparak ve \ alpha = 0 ayarlayarak α=0,

λminβ,β01Nλi=1N[yi(β0+xiTβ)+log(1+e(β0+xiTβ))]+||β||22/2

dan olan farklıdır sklearnsadece bir faktör ile maliyet fonksiyonu λ Eğer ayar 1Nλ=C , iki paketlerden aynı katsayısı tahmin bekliyor bu yüzden. Ama farklılar. Ben Idre UCLA'de veri kümesi kullanıyorum öğretici , tahmininde admitdayanan gre, gpave rank. 400 gözlem var, bu yüzden 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

RGörülebileceği gibi çıktı, regularization olmadan lojistik regresyon için bir türlü yakındır burada . Bir şey mi kaçırıyorum yoksa açık bir şekilde yanlış bir şey mi yapıyorum?

Güncelleme: Aynı işlemi yürütmek için LiblineaRpaketi de kullanmaya çalıştım Rve yine başka bir tahmin seti aldım ( liblinearaynı zamanda çözücüdür 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

Güncelleme 2: Standartlaşmayı kapatmak glmnet:

> 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

Bunu hiç çözdün mü?
Huey

Yanıtlar:


8

sklearn'ün lojistik regresyonu varsayılan olarak girdileri standartlaştırmaz, bu da düzenlenme teriminin anlamını değiştirir ; muhtemelen glmnet yapar.L2

Özellikle greteriminiz diğer değişkenlerden çok daha büyük bir ölçekte olduğu için, bu, ağırlıklar için farklı değişkenleri kullanmanın göreli maliyetlerini değiştirecektir.

Özelliklere açık bir kesişme terimi ekleyerek, modelin kesişimini düzenli hale getirdiğinizi de unutmayın. Bu genellikle yapılmaz, çünkü modeliniz artık tüm etiketleri bir sabitle kaydırmak için kovaryant değildir.


glmnetgirdilerin standardizasyonunun kapatılmasına izin verir, ancak tahmini katsayılar daha da farklıdır, lütfen yukarıya bakın. Da, açıkça dahil yolunu kesmek terimi sklearnNEDENİYLE glmnetbu emin iki modele girdi aynı olduğunu yapmaktır, böylece otomatik birini içerir.
hurrikale

2
@hurrikale Bence glmnet kesişimi düzenli değil ama sklearn öyle. Kesme sütununu bırakın Xve fit_intercept=True(varsayılan) 'a geçirin LogisticRegression. Yine de muhtemelen başka bir şey oluyor.
Dougal

: Ne önerdi ve henüz katsayısının farklı setler ne var çalıştı [-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]için sklearnve [-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]için glmnetsırasına göre [Intercept, rank_2, rank_3, rank_4, gre, gpa]. Benim endişem, hem büyüklük hem de olasılığı olumlu / olumsuz yönde etkilemeleri, bu yüzden neden farklı olduklarını bilmeden, yorumlanacak birini seçmek zor. Ve eğer uygulamalardan birinde bir hata varsa, hangisine güveneceğimi bilmek özellikle önemlidir.
hurrikale


0

Ayrıca , çağrıda L1_wt=0argüman kullanmalısınız .alphafit_regularized()

Bu kod şurada 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)

, şu kodla eşdeğerdir sklearn:

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

Umarım yardımcı olur!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.