Hồi quy logistic: Scikit Learn vs glmnet


15

Tôi đang cố gắng sao chép kết quả từ sklearnthư viện hồi quy logistic bằng glmnetgói trong R.

Từ tài liệusklearn hồi quy logistic , nó đang cố gắng giảm thiểu hàm chi phí theo hình phạt l2 min w , c 1

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

Từ các họa tiết của glmnet, việc triển khai của nó giảm thiểu hàm chi phí hơi khác nhau

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

Với một số điều chỉnh trong phương trình thứ hai và bằng cách đặt , λ min β , β 0 1α=0

λtối thiểuβ,β01NλΣTôi= =1N[-yTôi(β0+xTôiTβ)+đăng nhập(1+e(β0+xTôiTβ))]+||β||22/2

mà khác với sklearnhàm chi phí chỉ bằng một yếu tố của nếu thiết lập 1λ, vì vậy tôi đã mong đợi ước tính hệ số tương tự từ hai gói. Nhưng họ khác nhau. Tôi đang sử dụng dữ liệu từ UCLA idrehướng dẫn, dự đoándựa trên,và. Có 400 quan sát, như vậy vớiC=1,λ=0.0025.1Nλ= =CadmitgregparankC= =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

Đầu Rra bằng cách nào đó gần với hồi quy logistic mà không cần chính quy, như có thể thấy ở đây . Tôi đang thiếu một cái gì đó hoặc làm một cái gì đó rõ ràng sai?

Cập nhật: Tôi cũng đã thử sử dụng LiblineaRgói Rđể tiến hành cùng một quy trình và nhận được một bộ ước tính khác ( liblinearcũng là người giải quyết 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

Cập nhật 2: tắt tiêu chuẩn hóa trong glmnetcung cấp:

> 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

Bạn đã bao giờ con số này ra?
Huey

Câu trả lời:


8

Theo mặc định, hồi quy logistic của sklearn không chuẩn hóa các đầu vào, điều này làm thay đổi ý nghĩa của L2thời hạn chính quy; có lẽ glmnet nào.

Đặc biệt là từ gre thuật ngữ có quy mô lớn hơn các biến khác, điều này sẽ thay đổi chi phí tương đối của việc sử dụng các biến khác nhau cho trọng số.

Cũng lưu ý rằng bằng cách bao gồm một thuật ngữ chặn rõ ràng trong các tính năng, bạn đang thường xuyên hóa việc chặn mô hình. Điều này thường không được thực hiện, vì điều đó có nghĩa là mô hình của bạn không còn biến đổi để thay đổi tất cả các nhãn theo hằng số.


glmnetcho phép tắt tiêu chuẩn hóa đầu vào, nhưng các hệ số ước tính thậm chí còn khác nhau hơn, vui lòng xem ở trên. Ngoài ra, tôi bao gồm rõ ràng thuật ngữ chặn trong sklearnglmnetbao gồm một thuật ngữ tự động, vì vậy điều này là để đảm bảo rằng đầu vào cho cả hai mô hình đều giống nhau.
Hurrikale

2
@hurrikale Tôi nghĩ rằng glmnet có thể không thường xuyên đánh chặn, nhưng sklearn là. Thả cột chặn từ Xvà chuyển fit_intercept=True(mặc định) sang LogisticRegression. Có lẽ có một cái gì đó khác đang xảy ra là tốt.
Dougal

Tôi cố gắng những gì bạn đề nghị nhưng có bộ khác nhau của hệ số: [-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]cho sklearn[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]cho glmnettheo thứ tự [Intercept, rank_2, rank_3, rank_4, gre, gpa]. Mối quan tâm của tôi là chúng khác nhau cả về độ lớn và ảnh hưởng tích cực / tiêu cực đến xác suất, vì vậy mà không biết tại sao chúng khác nhau, thật khó để chọn một để giải thích. Và nếu có bất kỳ lỗi nào trong một trong các triển khai, điều đặc biệt quan trọng là tôi biết phải dựa vào cái nào.
Hurrikale

7

Câu trả lời của Dougal là chính xác, bạn thường xuyên chặn chặn trong sklearnnhưng không phải trong R. Hãy chắc chắn rằng bạn sử dụng solver='newton-cg'vì bộ giải mặc định ( 'liblinear') luôn thường xuyên chặn chặn.

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


Thiết lập solver='newton-cg'làm cho kết quả từ sklearnstatsmodelsnhất quán. Cảm ơn rất nhiều.
irene

0

Bạn cũng nên sử dụng L1_wt=0đối số cùng với alphatrong fit_regularized()cuộc gọi.

Mã này trong 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)

tương đương với đoạn mã sau từ sklearn:

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

Hy vọng nó giúp!

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.