【问题标题】:How to estimate many GLM models in Julia?如何估计 Julia 中的许多 GLM 模型?
【发布时间】:2020-08-28 08:09:23
【问题描述】:

我有一个包含 5000 个变量的数据集。一个目标和 4999 个协变量。我想为每个目标变量组合(4999 个模型)估计一个 glm。

如果不为 GLM 手动输入 4999 个公式,我该如何做到这一点?

在 R 中,我将简单地定义一个 4999 个字符串的列表 ("target ~ x1) ,将每个字符串转换为一个公式并使用 map 来估计多个 glm。在 Julia 中可以做类似的事情吗?或者是否有一个优雅的替代品?

提前致谢。

【问题讨论】:

    标签: julia


    【解决方案1】:

    您可以通过Term 对象以编程方式创建公式。可以在here 找到相关文档,但请考虑以下应该满足您需求的简单示例:

    从虚拟数据开始

    julia> using DataFrames, GLM
    
    julia> df = hcat(DataFrame(y = rand(10)), DataFrame(rand(10, 5)))
    10×6 DataFrame
    │ Row │ y         │ x1        │ x2       │ x3        │ x4         │ x5       │
    │     │ Float64   │ Float64   │ Float64  │ Float64   │ Float64    │ Float64  │
    ├─────┼───────────┼───────────┼──────────┼───────────┼────────────┼──────────┤
    │ 1   │ 0.0200963 │ 0.924856  │ 0.947904 │ 0.429068  │ 0.00833488 │ 0.547378 │
    │ 2   │ 0.169498  │ 0.0915296 │ 0.375369 │ 0.0341015 │ 0.390461   │ 0.835634 │
    │ 3   │ 0.900145  │ 0.502495  │ 0.38106  │ 0.47253   │ 0.637731   │ 0.814095 │
    │ 4   │ 0.255163  │ 0.865253  │ 0.791909 │ 0.0833828 │ 0.741899   │ 0.961041 │
    │ 5   │ 0.651996  │ 0.29538   │ 0.161443 │ 0.23427   │ 0.23132    │ 0.947486 │
    │ 6   │ 0.305908  │ 0.170662  │ 0.569827 │ 0.178898  │ 0.314841   │ 0.237354 │
    │ 7   │ 0.308431  │ 0.835606  │ 0.114943 │ 0.19743   │ 0.344216   │ 0.97108  │
    │ 8   │ 0.344968  │ 0.452961  │ 0.595219 │ 0.313425  │ 0.102282   │ 0.456764 │
    │ 9   │ 0.126244  │ 0.593456  │ 0.818383 │ 0.485622  │ 0.151394   │ 0.043125 │
    │ 10  │ 0.60174   │ 0.8977    │ 0.643095 │ 0.0865611 │ 0.482014   │ 0.858999 │
    

    现在,当您使用 GLM 运行线性模型时,您会执行类似 lm(@formula(y ~ x1), df) 的操作,这确实不能轻易地在循环中用于构造不同的公式。因此,我们将遵循文档并直接创建 @formula 宏的输出 - 请记住 Julia 中的宏只是将语法转换为其他语法,因此它们不会做任何我们自己无法编写的事情!

    julia> lm(Term(:y) ~ Term(:x1), df)
    StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}
    
    y ~ 1 + x1
    
    Coefficients:
    ──────────────────────────────────────────────────────────────────────────
                     Coef.  Std. Error      t  Pr(>|t|)   Lower 95%  Upper 95%
    ──────────────────────────────────────────────────────────────────────────
    (Intercept)   0.428436    0.193671   2.21    0.0579  -0.0181696   0.875041
    x1           -0.106603    0.304597  -0.35    0.7354  -0.809005    0.595799
    ──────────────────────────────────────────────────────────────────────────
    

    您可以自己验证上面是否等同于lm(@formula(y ~ x1), df)

    现在希望这是构建您正在寻找的循环的一个简单步骤(限制为以下两个协变量以限制输出):

    
    julia> for x ∈ names(df[:, Not(:y)])[1:2]
               @show lm(term(:y) ~ term(x), df)
           end
    lm(term(:y) ~ term(x), df) = StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}
    
    y ~ 1 + x1
    
    Coefficients:
    ──────────────────────────────────────────────────────────────────────────
                     Coef.  Std. Error      t  Pr(>|t|)   Lower 95%  Upper 95%
    ──────────────────────────────────────────────────────────────────────────
    (Intercept)   0.428436    0.193671   2.21    0.0579  -0.0181696   0.875041
    x1           -0.106603    0.304597  -0.35    0.7354  -0.809005    0.595799
    ──────────────────────────────────────────────────────────────────────────
    lm(Term(:y) ~ Term(x), df) = StatsModels.TableRegressionModel{LinearModel{GLM.LmResp{Array{Float64,1}},GLM.DensePredChol{Float64,LinearAlgebra.Cholesky{Float64,Array{Float64,2}}}},Array{Float64,2}}
    
    y ~ 1 + x2
    
    Coefficients:
    ─────────────────────────────────────────────────────────────────────────
                     Coef.  Std. Error      t  Pr(>|t|)  Lower 95%  Upper 95%
    ─────────────────────────────────────────────────────────────────────────
    (Intercept)   0.639633    0.176542   3.62    0.0068   0.232527    1.04674
    x2           -0.502327    0.293693  -1.71    0.1256  -1.17958     0.17493
    ─────────────────────────────────────────────────────────────────────────
    

    正如 Dave 在下面指出的那样,在此处使用 term() 函数而不是直接使用 Term() 构造函数来创建术语会很有帮助 - 这是因为 names(df) 返回一个 Strings 向量,而 @ 987654335@ 构造函数需要Symbols。 term() 有一个自动处理转换的 Strings 方法。

    【讨论】:

    • 这里不一定相关,但如果您的条款包含用于拦截的1,则可以直接使用“小写”term 函数而不是Term 构造函数。它还通过任何AbstractTerm 不变。 github.com/JuliaStats/StatsModels.jl/blob/master/src/…
    • 受这个问题的启发,我创建了一个拉取请求,该请求应该很快被合并(github.com/JuliaRegistries/General/pull/20638 这意味着)所以从 StatsModels 的 v0.6.14 开始,您可以直接执行 terms(names(df))terms 将转换字符串为你的符号
    • 可能值得编辑您的答案以反映这一点? 0.6.14 现已发布
    【解决方案2】:

    您还可以使用低级 API,将因变量作为向量传递,将自变量作为矩阵传递,甚至无需构建公式。您将丢失系数名称,但由于每个模型中只有一个自变量,因此可能没问题。

    这在?fit 中有记录。每个模型的调用看起来像glm([ones(length(x1)) x1], target, dist)。满一列是截距。

    【讨论】:

      猜你喜欢
      • 2013-04-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-17
      • 2015-12-09
      • 2022-01-25
      • 2016-12-26
      • 2018-09-15
      相关资源
      最近更新 更多