GLM R与Python的比较

3

我想在Python中生成一个逻辑回归,使其产生与R相同的结果。它看起来很接近,但并不完全相同。我编写了下面的示例来说明存在差异。这些数据是虚构的。

R

# RStudio 1.1.453

d <- data.frame(c(0, 0, 1, 1, 1),
                c(1, 0, 0, 0, 0),
                c(0, 1, 0, 0, 0))

colnames(d) <- c("v1", "v2", "v3")

model <- glm(v1 ~ v2,
         data = d,
         family = "binomial")


summary(model)

R输出

Call:
glm(formula = v1 ~ v2, family = "binomial", data = d)

Deviance Residuals: 
       1         2         3         4         5  
-1.66511  -0.00013   0.75853   0.75853   0.75853  

Coefficients:
            Estimate Std. Error z value Pr(>|z|)
(Intercept)    1.099      1.155   0.951    0.341
v2           -19.665   6522.639  -0.003    0.998

(Dispersion parameter for binomial family taken to be 1)

    Null deviance: 6.7301  on 4  degrees of freedom
Residual deviance: 4.4987  on 3  degrees of freedom
AIC: 8.4987

Number of Fisher Scoring iterations: 17

Python
# Python 3.7.1

import pandas as pd # 0.23.4
import statsmodels.api as sm # 0.9.0
import statsmodels.formula.api as smf # 0.9.0

d = pd.DataFrame({"v1" : [0, 0, 1, 1, 1],
                  "v2" : [1, 0, 0, 0, 0],
                  "v3" : [0, 1, 0, 0, 0]})

model = smf.glm(formula = "v1 ~ v2",
               family=sm.families.Binomial(link = sm.genmod.families.links.logit),
               data=d
               ).fit()

model.summary()

Python输出

                 Generalized Linear Model Regression Results                  
==============================================================================
Dep. Variable:                     v1   No. Observations:                    5
Model:                            GLM   Df Residuals:                        3
Model Family:                Binomial   Df Model:                            1
Link Function:                  logit   Scale:                          1.0000
Method:                          IRLS   Log-Likelihood:                -2.2493
Date:                Wed, 07 Nov 2018   Deviance:                       4.4987
Time:                        15:17:52   Pearson chi2:                     4.00
No. Iterations:                    19   Covariance Type:             nonrobust
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
Intercept      1.0986      1.155      0.951      0.341      -1.165       3.362
v2           -21.6647   1.77e+04     -0.001      0.999   -3.48e+04    3.47e+04
==============================================================================

迭代次数存在差异。据我所知,两者之间可能存在一些不同的收敛方法,但我不理解。是否存在其他设置我可能会错过?


4
考虑到你只有五个数据点且仅有一个非零值在v2中,我很惊讶两个系统都没有报错。这里提供的信息较少。如果你使用更大的数据集,并增加一些数据,你会发现它们接近甚至完全一致。 - Spacedman
1
你的数据量很小,可以手动计算对数似然并自行查看。这是一个图形 https://www.desmos.com/calculator/2vnvch2akx 。由于图形在向左移动时很快就变平了,但仍在增加,因此估计该函数的最大值不会收敛相同。他们对何时停止有不同的想法。标准误如此之大意味着在该区域内对数似然几乎完全平坦,这暗示了收敛问题。 - IceCreamToucan
我之前在自己的一个更大的数据集上进行了这个操作,但是现在为了验证结果,我编造了这个数据集。尤其是在比较多个变量时,结果仍然相当偏离。 - ackshooairy
1
同样的想法,对数似然曲率和标准误差成反比,因此如果您看到一个具有高标准误差的估计值,那意味着该区域周围的似然函数非常平坦,这意味着即使微小的收敛截止值差异也会产生非常不同的估计值。无论如何,这些估计值都不可靠,所以您不应该使用它们。 - IceCreamToucan
1
这是 SAS 超越 R 和 Python 的少数几次之一。我刚试着在 SAS 中用 PROC LOGISTIC 运行了这个程序,并得到了正确的警告:“模型收敛状态:检测到数据点的准完全分离。最大似然估计可能不存在。”(正如您在图表中所看到的,该函数确实没有最大值)。关于“什么是准完全分离?”请参见 https://stats.idre.ucla.edu/other/mult-pkg/faq/general/faqwhat-is-complete-or-quasi-complete-separation-in-logisticprobit-regression-and-how-do-we-deal-with-them/。 - IceCreamToucan
1个回答

2

我猜测它们在数值稳定性方面有不同的权衡。

v2 估计的方差非常大,这可能导致它们都很难处理... 我想他们基本上给出了相同的答案,至少在双精度算术的限制下。

R 实现允许您传递一个 control 参数:

> options(digits=12)
> model <- glm(v1 ~ v2, data=d, family="binomial", control=list(trace=T))
Deviance = 4.67724333758 Iterations - 1
Deviance = 4.5570420311 Iterations - 2
Deviance = 4.51971688994 Iterations - 3
Deviance = 4.50636401333 Iterations - 4
Deviance = 4.50150009179 Iterations - 5
Deviance = 4.49971718523 Iterations - 6
Deviance = 4.49906215541 Iterations - 7
Deviance = 4.49882130019 Iterations - 8
Deviance = 4.4987327103 Iterations - 9
Deviance = 4.49870012203 Iterations - 10
Deviance = 4.49868813377 Iterations - 11
Deviance = 4.49868372357 Iterations - 12
Deviance = 4.49868210116 Iterations - 13
Deviance = 4.4986815043 Iterations - 14
Deviance = 4.49868128473 Iterations - 15
Deviance = 4.49868120396 Iterations - 16
Deviance = 4.49868117424 Iterations - 17

这段代码显示了收敛性,但我在 Python 代码中找不到类似的内容。

从上面的输出可以看出,他们可能也使用不同的截止值来确定收敛性;R 使用 epsilon = 1e-8


谢谢。这很有帮助。我应该澄清一下,我只是编造了这些数据。由于对R的无知,我曾经在Python和R中尝试制作相同的大型数据集,但在使用真实数据时看到了类似的结果。 - ackshooairy
2
不同的实现几乎总会产生不同的结果,上述v2估计值的差异是(估计的)标准偏差的<0.1%。你所说的“在真实数据上获得类似的结果”是什么意思? - Sam Mason
看起来很合理。我大约有80K行数据,发现截距相差50%以上。我非常愿意承认我可能对它们的解释存在误解。我将尝试使用更大的数据重现我的示例,以代表我的情况。 - ackshooairy
你想要比较系数估计值及其标准误差。我只会预期这种影响在z分数接近0或p值接近1的系数中才会显著。 - Sam Mason

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接