การถดถอยโลจิสติก: Scikit Learn vs glmnet


15

ฉันพยายามทำซ้ำผลลัพธ์จากsklearnไลบรารีถดถอยโลจิสติกโดยใช้glmnetแพคเกจใน R

จากเอกสารsklearnการถดถอยโลจิสติกพยายามลดฟังก์ชั่นค่าใช้จ่ายภายใต้บทลงโทษ l2 ขั้นต่ำw , c 1

minw,12wTW+Σผม=1ยังไม่มีข้อความเข้าสู่ระบบ(ประสบการณ์(-Yผม(XผมTW+))+1)

จากสะเปะสะปะของglmnetการดำเนินงานของฟังก์ชั่นช่วยลดค่าใช้จ่ายแตกต่างกันเล็กน้อย

นาทีβ,β0-[1ยังไม่มีข้อความΣผม=1ยังไม่มีข้อความYผม(β0+xผมTβ)-เข้าสู่ระบบ(1+อี(β0+xผมTβ))]+λ[(α-1)||β||22/2+α||β||1]

ด้วยการบิดในสมการที่สองและด้วยการตั้งค่า , λ นาทีβ , β 0 1α=0

λนาทีβ,β01ยังไม่มีข้อความλΣผม=1ยังไม่มีข้อความ[-Yผม(β0+xผมTβ)+เข้าสู่ระบบ(1+อี(β0+xผมTβ))]+||β||22/2

ซึ่งแตกต่างจากsklearnฟังก์ชั่นค่าใช้จ่ายโดยปัจจัยถ้าตั้งค่า1λดังนั้นฉันจึงคาดว่าค่าสัมประสิทธิ์ประมาณเดียวกันจากทั้งสองแพคเกจ แต่พวกเขาแตกต่างกัน ฉันใช้ชุดข้อมูลจาก UCLA Idreกวดวิชาทำนายบนพื้นฐาน,และ มี 400 ข้อสังเกตดังนั้นด้วยC=1,λ=0.00251ยังไม่มีข้อความλ=admitgregparank=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

Rการส่งออกเป็นอย่างใดใกล้กับถดถอยโลจิสติโดยไม่ต้อง regularization ที่สามารถมองเห็นได้ที่นี่ ฉันทำอะไรผิดพลาดหรือทำอะไรผิดอย่างชัดเจนหรือไม่?

อัปเดต: ฉันพยายามใช้LiblineaRแพคเกจRเพื่อดำเนินการกระบวนการเดียวกัน แต่ยังมีชุดการประมาณการอื่นอีกชุดหนึ่ง ( liblinearเป็นตัวแก้ปัญหาด้วย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

อัปเดต 2: ปิดมาตรฐานในการ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

คุณเคยคิดเรื่องนี้ไหม?
ฮิวอี้

คำตอบ:


8

การถดถอยโลจิสติกของ sklearn ไม่ได้มาตรฐานอินพุตโดยค่าเริ่มต้นซึ่งเปลี่ยนความหมายของ L2การทำให้เป็นมาตรฐาน อาจเป็น glmnet

โดยเฉพาะอย่างยิ่งเนื่องจากgreคำของคุณมีขนาดใหญ่กว่าตัวแปรอื่น ๆ สิ่งนี้จะเปลี่ยนต้นทุนสัมพัทธ์ของการใช้ตัวแปรต่าง ๆ สำหรับน้ำหนัก

โปรดทราบว่าด้วยการรวมคำดักจับที่ชัดเจนในคุณลักษณะต่างๆคุณกำลังทำให้การสกัดกั้นของโมเดลเป็นปกติ โดยทั่วไปจะไม่ทำเพราะหมายความว่าแบบจำลองของคุณจะไม่แปรปรวนอีกต่อไปที่จะเปลี่ยนฉลากทั้งหมดด้วยค่าคงที่


glmnetอนุญาตให้ปิดมาตรฐานอินพุต แต่ค่าสัมประสิทธิ์โดยประมาณแตกต่างกันมากขึ้นโปรดดูด้านบน นอกจากนี้ฉันได้รวมคำดักจับไว้อย่างชัดเจนsklearnเนื่องจากglmnetมีหนึ่งรายการโดยอัตโนมัติดังนั้นนี่คือเพื่อให้แน่ใจว่าอินพุตของทั้งสองรุ่นเหมือนกัน
hurrikale

2
@Hurrikale ฉันคิดว่า glmnet อาจไม่ทำให้การสกัดกั้นเป็นปกติ แต่เป็นความผิดพลาด วางคอลัมน์ตัดจากXและผ่านfit_intercept=True(ค่าเริ่มต้น) LogisticRegressionเพื่อ แม้ว่าอาจมีสิ่งอื่นเกิดขึ้นเช่นกัน
Dougal

ฉันพยายามสิ่งที่คุณแนะนำและยังมีชุดที่แตกต่างของค่าสัมประสิทธิ์: [-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]สำหรับsklearnและ[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]สำหรับในคำสั่งของglmnet [Intercept, rank_2, rank_3, rank_4, gre, gpa]ความกังวลของฉันคือพวกเขาแตกต่างกันทั้งในขนาดและในเชิงบวก / เชิงลบที่มีผลต่อความน่าจะเป็นดังนั้นโดยไม่ทราบว่าทำไมพวกเขาแตกต่างกันมันยากที่จะเลือกหนึ่งที่จะตีความ และหากมีข้อผิดพลาดในการใช้งานอย่างใดอย่างหนึ่งมันเป็นสิ่งสำคัญโดยเฉพาะอย่างยิ่งที่ฉันรู้ว่าสิ่งที่ต้องพึ่งพา
hurrikale

7

คำตอบของ Dougal นั้นถูกต้องคุณทำให้การสกัดกั้นเป็นปกติsklearnแต่ไม่ใช่ในอาร์ตรวจสอบให้แน่ใจว่าคุณใช้solver='newton-cg'ตั้งแต่ตัวแก้ค่าเริ่มต้น ( 'liblinear') จะทำการสกัดกั้นเสมอ

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


การตั้งค่าsolver='newton-cg'ทำให้ผลลัพธ์จากsklearnและstatsmodelsสอดคล้องกัน ขอบคุณมาก.
irene

0

นอกจากนี้คุณยังควรใช้L1_wt=0อาร์กิวเมนต์พร้อมกับalphaในfit_regularized()การโทร

รหัสนี้ใน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)

เทียบเท่ากับรหัสต่อไปนี้จากsklearn:

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

หวังว่ามันจะช่วย!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.