逻辑回归:Scikit Learn与glmnet


15

我正在尝试sklearn使用glmnetR中的包复制逻辑回归库的结果。

sklearn

wC1个2wŤw+C一世=1个ñ日志经验值-ÿ一世X一世Ťw+C+1个

从的渐近点来看glmnet,它的实现将成本函数

ββ0-[1个ñ一世=1个ñÿ一世β0+X一世Ťβ-日志1个+Ëβ0+X一世Ťβ]+λ[α-1个||β||22/2+α||β||1个]

在第二个公式中进行一些调整,并设置,\ lambda \ min _ {\ beta,\ beta_0} \ frac1 {N \ lambda} \ sum_ {i = 1} ^ N \ left [-y_i(\ beta_0 + x_i ^ T \ beta)+ \ log(1 + e ^ {(\ beta_0 + x_i ^ T \ beta)})\ right] + || \ beta || _2 ^ 2/2α=0

λββ01个ñλ一世=1个ñ[-ÿ一世β0+X一世Ťβ+日志1个+Ëβ0+X一世Ťβ]+||β||22/2

其不同于sklearn成本函数只通过一个因子λ如果集合1个ñλ=C,所以我期待从两个包相同的系数估计。但是它们是不同的。我使用从加州大学洛杉矶分校idre数据集教程,预测admit基础上gregparank。有400个观测值,因此C=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输出是有点接近回归没有转正,可以看出这里。我是想念东西还是做错了明显的事?

更新:我还尝试使用LiblineaRpackage in 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

你有没有解决这个问题?
休伊

Answers:


8

sklearn的逻辑回归默认情况下不对输入进行标准化,从而更改了正则化项的含义;glmnet大概可以。大号2

特别是因为您的gre术语比其他变量的范围更大,这将改变使用不同变量作为权重的相对成本。

还要注意,通过在功能中包括显式的拦截项,您可以规范模型的拦截。通常不会这样做,因为这意味着您的模型不再与将所有标签移动一个常数协变。


glmnet允许关闭输入的标准化,但是估计系数甚至更大,请参见上文。另外,我明确在其中包含了拦截项,sklearn因为glmnet它会自动包含一个,所以这是为了确保两个模型的输入都相同。
hurrikale 2016年

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中对截距进行正则化,而不能在R中进行正则化。solver='newton-cg'由于默认的求解器('liblinear')始终对截距进行正则化,因此请务必使用。

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


设置solver='newton-cg'做出的结果从sklearnstatsmodels一致。非常感谢。
irene,

0

您还应该将L1_wt=0参数与alphain 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)

希望能帮助到你!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.