로지스틱 회귀 분석 : Scikit Learn 및 glmnet


15

R의 패키지를 sklearn사용하여 로지스틱 회귀 라이브러리 의 결과를 복제하려고합니다 glmnet.

로부터 sklearn로지스틱 회귀 문서 , L2 페널티 아래의 비용 함수를 최소화하기 위해 노력하고있다

minw,c12wTw+C나는=1로그(특급(와이나는(엑스나는+))+1)

로부터 네트glmnet그 구현이 약간 다른 비용 함수를 최소화하는

β,β0[1나는=1와이나는(β0+엑스나는β)로그(1+이자형(β0+엑스나는β))]+λ[(α1)||β||22/2+α||β||1]

제 방정식과 설정하여 일부 비틀기 , λ β는 , β 0 1α=0

λβ,β01λ나는=1[와이나는(β0+엑스나는β)+로그(1+이자형(β0+엑스나는β))]+||β||22/2

1로 설정하면 λsklearn 의 계수 만 비용 함수 와 다릅니다.λ이므로 두 패키지에서 동일한 계수 추정을 기대하고있었습니다. 그러나 그들은 다릅니다. 나는 idre UCLA에서 데이터 세트 사용하고자습서를예측,기반,그리고. C=1,λ=0.0025로 400 개의 관측 값이 있습니다.1λ=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볼 수 있듯이 출력은 정규화없이 로지스틱 회귀 분석에 어떻게 든 가까운 여기 . 뭔가 빠졌거나 분명히 잘못하고 있습니까?

업데이트 : 나는 또한 동일한 프로세스를 수행 하기 위해 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

이것을 알아 낸 적이 있습니까?
Huey

답변:


8

2

특히 gre용어가 다른 변수보다 규모가 크므로 가중치에 다른 변수를 사용하는 상대 비용이 변경됩니다.

피처에 명시 적 절편을 포함시킴으로써 모델의 절편을 정규화 할 수 있습니다. 이것은 모델이 더 이상 모든 레이블을 상수만큼 이동시키는 공변량이 아니기 때문에 일반적으로 수행되지 않습니다.


glmnet입력의 표준화를 끌 수 있지만 추정 계수는 훨씬 다릅니다. 위를 참조하십시오. 또한 자동으로 하나를 포함 sklearn하기 때문에 인터셉트 용어를 명시 적으로 포함 했으므로 glmnet두 모델의 입력이 동일해야합니다.
hurrikale

2
@hurrikale 나는 glmnet이 아마도 가로 채기를 규칙 화하지는 않지만 sklearn은 생각합니다. 가로 채기 열을 삭제하고 (기본값)을 X전달 fit_intercept=True하십시오 LogisticRegression. 그래도 다른 일이있을 수 있습니다.
Dougal

나는 당신이 제안한 것을 시도했지만 [-1.873, -0.0606, -1.175, -1.378, 0.00182, 0.2435]for sklearn[-2.8181, 0.0001269, -0.0002259, -0.00020288, 0.00344, 0.000188]for glmnet의 순서로 다른 계수 세트를 얻었습니다 [Intercept, rank_2, rank_3, rank_4, gre, gpa]. 저의 관심사는 그것들의 크기와 확률에 긍정적 / 부정적으로 영향을 미치기 때문에 그들이 왜 다른지 알지 못한다면, 해석 할 하나를 선택하기가 어렵습니다. 그리고 만약 구현 중 하나에 버그가 있다면, 어느 것이 의존해야하는지 아는 것이 특히 중요합니다.
hurrikale

7

Dougal의 대답은 정확합니다. 인터셉트를 정규화 sklearn하지만 R 에서는 정규화 하지 마십시오. solver='newton-cg'기본 솔버 ( 'liblinear')는 항상 인터셉트를 정규화 하므로 사용하십시오 .

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


설정을 solver='newton-cg'에서 결과를 만들어 sklearnstatsmodels일치. 고마워
아이린

0

또한 사용해야 L1_wt=0과 함께 인수 alphafit_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.