You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将先验均值与标准差变量传入brms模型?

在brms中使用变量传递先验参数的解决方法

你遇到的问题是因为brms生成Stan代码时,不会自动解析prior()函数里的R变量,而是直接将变量名写入Stan代码,导致Stan编译器无法识别这些仅存在于R环境中的变量。下面是两种可行的解决方法:

方法1:使用准引用强制求值

利用R的准引用语法(!!操作符),让R先将变量替换为具体数值,再传递给brms。修改后的代码如下:

library(tidyverse)
library(brms)

df_demo = 
    tibble(
        A = rbinom(1e3, 1, .5),
        B = rbinom(1e3, 1, .51),
    ) |> 
    pivot_longer(
        everything(),
        names_to = "recipe",
        values_to = "convert"
    )

MU_INTERCEPT = 0
SD_INTERCEPT = 0.1003353
MU_TRT = 0
SD_TRT = 0.02000267

brm(
    formula = "convert ~ recipe",
    prior =
        prior(normal(!!MU_INTERCEPT, !!SD_INTERCEPT), class = Intercept) +
        prior(normal(!!MU_TRT, !!SD_TRT), class = b, coef=recipeB),
    data = df_demo, 
    family = bernoulli
) 

!!会强制R对后续变量求值,把变量的实际数值代入先验定义,生成的Stan代码里就会是具体数字而非变量名,Stan就能正常编译。

方法2:构造字符串形式的先验

如果不习惯准引用,也可以直接通过字符串拼接生成先验规则,再传给prior参数:

library(tidyverse)
library(brms)

df_demo = 
    tibble(
        A = rbinom(1e3, 1, .5),
        B = rbinom(1e3, 1, .51),
    ) |> 
    pivot_longer(
        everything(),
        names_to = "recipe",
        values_to = "convert"
    )

MU_INTERCEPT = 0
SD_INTERCEPT = 0.1003353
MU_TRT = 0
SD_TRT = 0.02000267

# 拼接先验字符串
prior_str = paste0(
    "normal(", MU_INTERCEPT, ", ", SD_INTERCEPT, ") class=Intercept; ",
    "normal(", MU_TRT, ", ", SD_TRT, ") class=b coef=recipeB"
)

brm(
    formula = "convert ~ recipe",
    prior = prior_str,
    data = df_demo, 
    family = bernoulli
)

这种方式通过字符串拼接直接将变量值写入先验规则,同样能避免Stan识别R变量的问题。

错误原因说明

你之前的代码中,prior(normal(MU_INTERCEPT, SD_INTERCEPT), class = Intercept)会被brms直接转换成Stan代码里的normal_lpdf(Intercept | MU_INTERCEPT, SD_INTERCEPT),但Stan环境中没有定义MU_INTERCEPT这类变量,因此抛出“标识符不在作用域内”的错误。上述两种方法的核心都是让R先把变量替换为具体数值,再生成合法的Stan代码。

内容的提问来源于stack exchange,提问作者Joe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 21:33:19