【问题标题】:Mixed effects logistic regression混合效应逻辑回归
【发布时间】:2020-02-25 21:43:56
【问题描述】:

我正在尝试在 python 中实现混合效果逻辑回归。作为比较点,我使用的是 R 中 lme4 包中的 glmer 函数。

我发现statsmodels 模块有一个BinomialBayesMixedGLM 应该能够适应这样的模型。但是,我遇到了一些问题:

  1. 我发现 statsmodels 函数的文档并不完全有用或清晰,因此我不完全确定如何正确使用该函数。
  2. 到目前为止,我的尝试并没有产生与我在 R 中使用 glmer 拟合模型时得到的结果相同的结果。
  3. 我预计 BinomialBayesMixedGLM 函数不会计算 p 值,因为它是贝叶斯,但我似乎无法弄清楚如何访问参数的完整后验分布。

作为测试用例,我使用的是可用的泰坦尼克数据集here

import os
import pandas as pd
import statsmodels.genmod.bayes_mixed_glm as smgb

titanic = pd.read_csv(os.path.join(os.getcwd(), 'titanic.csv'))

r = {"Pclass": '0 + Pclass'}
mod = smgb.BinomialBayesMixedGLM.from_formula('Survived ~ Age', r, titanic)
fit = mod.fit_map()
fit.summary()

#           Type    Post. Mean  Post. SD       SD SD (LB) SD (UB)
# Intercept M           3.1623    0.3616            
# Age       M          -0.0380    0.0061            
# Pclass    V           0.0754    0.5669    1.078   0.347   3.351

但是,除了 Age 的斜率之外,这似乎与我在 R 中得到的 glmer(Survived ~ Age + (1 | Pclass), data = titanic, family = "binomial") 不匹配:

Random effects:
 Groups Name        Variance Std.Dev.
 Pclass (Intercept) 0.8563   0.9254  
Number of obs: 887, groups:  Pclass, 3

Fixed effects:
             Estimate Std. Error z value Pr(>|z|)    
(Intercept)  0.961780   0.573402   1.677   0.0935 .  
Age         -0.038708   0.006243  -6.200 5.65e-10 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

那么在 python 中创建模型时我犯了什么错误?而且,一旦解决了这个问题,我该如何提取后验值或 p 值?最后,他们是否有任何混合效应逻辑回归的 Python 实现更类似于 R 中的实现?

【问题讨论】:

  • @petezurich -- 据我所知,为什么要编辑标题,这样就不再清楚地表明我的问题是关于如何在 python 中拟合这种类型的模型?对于寻找类似问题的答案的其他人来说,新标题的描述性似乎应该更小。
  • 这就是标签的用途。见this post“在你的问题标题中包含标签是完全没有必要的。”
  • 顺便说一句:您的问题似乎跑题了,很可能会被关闭。来自help center“要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件。相反,描述问题以及迄今为止为解决该问题所做的工作。”
  • @petezurich 感谢您的澄清和提示。经过更多的工作,我更新了我的问题。
  • 可能是 Bambi 或 Pymer4

标签: python logistic-regression mixed-models


【解决方案1】:

只需按照 cmets Pymer4 中的建议对 Python 做类似的事情 似乎提供了一种合适的方法(尤其是如果您无论如何都熟悉R)。 使用问题中提到的示例数据集“泰坦尼克号”:

from pymer4.models import Lmer

model = Lmer("Survived  ~ Age  + (1|Pclass)",
             data=titanic, family = 'binomial')

print(model.fit())

输出:

Formula: Survived~Age+(1|Pclass)

Family: binomial     Inference: parametric

Number of observations: 887  Groups: {'Pclass': 3.0}

Log-likelihood: -525.812     AIC: 1057.624

Random effects:

               Name    Var    Std
Pclass  (Intercept)  0.856  0.925

No random effect correlations specified

Fixed effects:

             Estimate  2.5_ci  97.5_ci     SE     OR  OR_2.5_ci  OR_97.5_ci  \
(Intercept)     0.962  -0.162    2.086  0.573  2.616       0.85       8.050   
Age            -0.039  -0.051   -0.026  0.006  0.962       0.95       0.974   

              Prob  Prob_2.5_ci  Prob_97.5_ci  Z-stat  P-val  Sig  
(Intercept)  0.723        0.460         0.889   1.677  0.093    .  
Age          0.490        0.487         0.493  -6.200  0.000  *** 

作为附加评论(很抱歉转移了主要问题),我在Ubuntu 20.04 机器上运行了这个Python 3.8.8。不确定是否有其他人遇到过这个问题,但是当使用Pymer4 运行上面的模型时,包抛出了一个错误(当我尝试从Pymer4 文档here 复制类似的模型时出现同样的错误):

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

参考/pymer4/models/Lmer.py包文件中的这一行:

--> 444         if design_matrix:

我通过将其更改为来解决此问题(不确定这是否是最优雅或最安全的方法,很高兴在这里得到纠正):

if design_matrix.any():

这似乎使程序包运行起来,并在我测试的少数情况下提供了与 R 等效的结果。

以下 cmets 建议的更好方法可能是:

if design_matrix is not None:

感谢 Giacomo Petrillo 指出这一点,不过我还没有对此进行测试。

【讨论】:

  • 使用design_matrix.any() 可能是错误的,if design_matrix: 的预期含义是检查它是否为None(替换为if design_matrix is not None:)或检查它是否不是空数组(@ 987654339@).
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-10
  • 1970-01-01
  • 1970-01-01
  • 2023-04-05
  • 1970-01-01
  • 2013-08-27
  • 2015-08-05
相关资源
最近更新 更多