로지스틱 회귀 : Scikit Learn 및 Statsmodels


31

이 두 라이브러리의 로지스틱 회귀 출력에서 ​​다른 결과를 얻는 이유를 이해하려고합니다.

나는 idre UCLA에서 데이터 세트 사용하고 자습서를 예측, admit기반 gre, gpa그리고 rank. rank는 범주 형 변수로 취급되므로 먼저 rank_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는 idre 웹 사이트에 표시된 것과 동일하지만 scikit-learn이 다른 계수 세트를 생성하는 이유를 모르겠습니다. 다른 손실 기능을 최소화합니까? 구현에 관한 문서가 있습니까?

답변:


28

이를 알아내는 데 대한 힌트는 scikit-learn 추정치로부터 얻은 모수 추정치가 statsmodels 대응 치보다 균일하게 작다는 것입니다. 이것은 scikit-learn이 일종의 매개 변수 정규화를 적용한다고 믿게 할 수 있습니다. scikit-learn documentation 을 읽고이를 확인할 수 있습니다 .

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-learn에서 정규화를 끄는 가장 좋은 방법은을 설정하는 것 penalty='none'입니다.
Nzbuu

3

또 다른 차이점은 실제로 다른 모델 인 fit_intercept = False를 설정했다는 것입니다. Statsmodel에 절편이 포함되어 있음을 알 수 있습니다. 절편이 없으면 피처의 예상 가중치가 변경됩니다. 다음을 시도하고 비교해보십시오.

model = LogisticRegression(C=1e9)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.