1 回答
TA贡献1780条经验 获得超5个赞
您的代码存在一些问题。
首先,您在此处显示的两个模型并不相同:尽管您适合 scikit-learn LogisticRegression
(fit_intercept=True
这是默认设置),但您不会使用 statsmodels 模型;来自 statsmodels文档:
默认情况下不包含拦截,应由用户添加。看
statsmodels.tools.add_constant
。
这似乎是一个常见的混淆点 - 例如scikit-learn 和 statsmodels - 哪个 R 平方是正确的?(也有自己的答案)。
另一个问题是,尽管您处于二元分类设置中,但您要求multi_class='multinomial'
在您的 中LogisticRegression
,但事实并非如此。
第三个问题是,正如相关的交叉验证线程逻辑回归:Scikit Learn vs Statsmodels中所解释的那样:
没有办法在 scikit-learn 中关闭正则化,但是您可以通过将调整参数 C 设置为较大的数字来使其无效。
这使得这两个模型在原则上再次不可比,但您已经通过设置在此处成功解决了这个问题C=1e8
。事实上,从那时起(2016 年),scikit-learn 确实添加了一种关闭正则化的方法penalty='none'
,根据文档,通过设置 since :
如果为“无”(liblinear 求解器不支持),则不应用正则化。
现在应该将其视为关闭正则化的规范方法。
因此,将这些更改合并到您的代码中,我们有:
np.random.seed(42) # for reproducibility
#### Statsmodels
# first artificially add intercept to x, as advised in the docs:
x_ = sm.add_constant(x)
res_sm = sm.Logit(y, x_).fit(method="ncg", maxiter=max_iter) # x_ here
print(res_sm.params)
这给出了结果:
Optimization terminated successfully.
Current function value: 0.403297
Iterations: 5
Function evaluations: 6
Gradient evaluations: 10
Hessian evaluations: 5
[-1.65822763 3.65065752]
数组的第一个元素是截距,第二个元素是 的系数x。而对于 scikit 学习,我们有:
#### Scikit-Learn
res_sk = LogisticRegression(solver='newton-cg', max_iter=max_iter, fit_intercept=True, penalty='none')
res_sk.fit( x.reshape(n, 1), y )
print(res_sk.intercept_, res_sk.coef_)
结果是:
[-1.65822806] [[3.65065707]]
在机器的数字精度范围内,这些结果实际上是相同的。
对不同的值重复该过程np.random.seed()不会改变上面显示的结果的本质。
添加回答
举报