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


31

ฉันพยายามที่จะเข้าใจว่าทำไมผลลัพธ์จากการถดถอยโลจิสติกส์ของห้องสมุดทั้งสองนี้จึงให้ผลลัพธ์ที่แตกต่างกัน

ฉันใช้ชุดข้อมูลจาก UCLA Idre กวดวิชาทำนายadmitบนพื้นฐานgre, และgpa ถูกใช้เป็นตัวแปรเด็ดขาดดังนั้นจึงถูกแปลงเป็นตัวแปรดัมมีการดร็อป คอลัมน์ดักจะถูกเพิ่มด้วยrankrankrank_1

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

ผลลัพธ์จากstatsmodelsสิ่งเดียวกันกับที่แสดงบนเว็บไซต์ของคนขี้เกียจ แต่ฉันไม่แน่ใจว่าทำไม scikit-learn สร้างชุดของค่าสัมประสิทธิ์ที่แตกต่างกัน มันลดฟังก์ชั่นการสูญเสียที่แตกต่างกันบ้างไหม? มีเอกสารใดบ้างที่ระบุถึงการนำไปปฏิบัติ

คำตอบ:


28

เงื่อนงำของคุณในการหาสิ่งนี้ควรเป็นไปได้ว่าพารามิเตอร์ประมาณการจากการประมาณค่า scikit-Learn นั้นมีขนาดเล็กกว่าขนาดสถิติเท่ากัน สิ่งนี้อาจทำให้คุณเชื่อว่า scikit-Learn ใช้การทำให้เป็นมาตรฐานของพารามิเตอร์ คุณสามารถยืนยันนี้โดยการอ่านเอกสาร scikit เรียนรู้

ไม่มีวิธีปิดการทำให้เป็นมาตรฐานใน scikit-learn แต่คุณสามารถทำให้มันไม่มีประสิทธิภาพได้โดยการตั้งค่าพารามิเตอร์การปรับCเป็นจำนวนมาก นี่คือวิธีการทำงานในกรณีของคุณ:

# 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

ขอบคุณมากสำหรับคำอธิบาย! ด้วยผลลัพธ์ปกตินี้ฉันพยายามทำซ้ำผลลัพธ์โดยใช้glmnetแพ็คเกจใน R แต่ไม่สามารถรับค่าสัมประสิทธิ์เดียวกันได้ glmnetมีฟังก์ชั่นค่าใช้จ่ายแตกต่างกันเล็กน้อยเมื่อเทียบกับsklearnแต่แม้ว่าฉันจะตั้งค่าalpha=0ในglmnet(หมายถึงเพียงใช้ L2 โทษ) และชุดที่1/(N*lambda)=Cผมยังไม่ได้รับผลเดียวกันได้หรือไม่
hurrikale

สัญชาตญาณของฉันคือถ้าฉันหารทั้งสองแง่ของฟังก์ชันต้นทุนglmnetด้วยlambdaและตั้งค่าคงที่ใหม่ในแบบอักษรของความน่าจะเป็นบันทึกซึ่ง1/(N*lambda)เท่ากับว่าในsklearnนั้นฟังก์ชันต้นทุนทั้งสองจะเหมือนกันหรือฉันขาดอะไรไป
hurrikale

@hurrikale ถามคำถามใหม่และเชื่อมโยงได้ที่นี่และฉันจะดู
tchakravarty

ขอบคุณ! ผมโพสต์คำถามที่นี่
hurrikale

ผมคิดว่าวิธีที่ดีที่สุดเพื่อปิดกูใน scikit penalty='none'เรียนรู้คือโดยการตั้งค่า
Nzbuu

3

ความแตกต่างอีกอย่างก็คือคุณได้ตั้งค่า fit_intercept = False ซึ่งเป็นรูปแบบที่แตกต่างกันอย่างมีประสิทธิภาพ คุณจะเห็นว่า Statsmodel มีการสกัดกั้น การไม่มีการดักจับเป็นการเปลี่ยนแปลงน้ำหนักที่คาดหวังของคุณสมบัติอย่างแน่นอน ลองสิ่งต่อไปนี้และดูว่ามันเปรียบเทียบอย่างไร:

model = LogisticRegression(C=1e9)

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