如何在brms中为广义可加模型平滑变量s()设置固定与随机效应先验?
问题描述
如何在brms的set_prior命令中,为brms集成的广义可加模型(GAM)的固定效应和随机效应部分中的平滑变量s()设置先验?具体来说,需要为平滑变量sDev_Yr_1设置非平坦先验,同时要考虑该变量随Dev_Yr取值范围变化的情况,该如何定义这个单一平滑变量的先验?
所用模型代码
Model_GAM <- brm( bf(Trended_Incr_PP_Def ~ Dev_Yr_1_Factor + s(Dev_Yr, k=3, m=2) + Cal_Yr_Time, sigma ~ 0 + Intercept + Dev_Yr_6_Cap + Dev_Yr_10_Spline ), iter = 4000, prior = GAM_prior, seed = 8603529, control = list(adapt_delta = .99 ), data = Train_Triangle_All_Operation, family = lognormal() )
模型摘要输出
summary(Model_GAM) Family: lognormal Links: mu = identity; sigma = log Formula: Trended_Incr_PP_Def ~ Dev_Yr_1_Factor + s(Dev_Yr, k = 3, m = 2) + Cal_Yr_Time sigma ~ 0 + Intercept + Dev_Yr_6_Cap + Dev_Yr_10_Spline 数据:Train_Triangle_All_Operation(观测数:253) 抽样:4条链,每条链iter=4000;warmup=2000;thin=1; 热身完成后总抽样数:8000 平滑项: Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS sds(sDev_Yr_1) 14.27 6.99 6.67 32.76 1.00 3983 4393 总体水平效应: Estimate Est.Error l-95% CI u-95% CI Rhat Bulk_ESS Tail_ESS Intercept -0.77 0.27 -1.30 -0.24 1.00 7033 5186 Dev_Yr_1_Factor2 5.10 0.28 4.57 5.66 1.00 6507 4634 Cal_Yr_Time 0.01 0.00 0.00 0.02 1.00 8006 4830 sigma_Intercept 0.53 0.09 0.35 0.71 1.00 4214 4553 sigma_Dev_Yr_6_Cap -0.33 0.03 -0.38 -0.27 1.00 4068 4369 sigma_Dev_Yr_10_Spline 0.09 0.03 0.03 0.16 1.00 3858 3521 sDev_Yr_1 2.01 0.09 1.86 2.22 1.00 3677 3162 抽样采用sampling(NUTS)方法。对于每个参数,Bulk_ESS和Tail_ESS为有效样本量指标,Rhat为拆分链的潜在尺度缩减因子(收敛时Rhat=1)。 警告信息: 热身完成后出现5次发散转移。将adapt_delta提高到0.99以上可能有所帮助。
当前先验设置摘要
| prior | class | coef | group | resp | dpar | nlpar | lb | ub | source |
|---|---|---|---|---|---|---|---|---|---|
| (flat) | b | default | |||||||
| normal(0.02, 0.01) | b | Cal_Yr_Time | user | ||||||
| normal(1, 0.95) | b | Dev_Yr_1_Factor2 | user | ||||||
| (flat) | b | sDev_Yr_1 | (vectorized) | ||||||
| (flat) | b | sigma | default | ||||||
| student_t(3, 0.1, 0.05) | b | Dev_Yr_10_Spline | sigma | user | |||||
| normal(-0.1, 0.05) | b | Dev_Yr_6_Cap | sigma | user | |||||
| normal(0.2, 0.1) | b | Intercept | sigma | user | |||||
| student_t(3, 4.4, 2.5) | Intercept | default | |||||||
| student_t(3, 0, 2.5) | sds | 0 | default | ||||||
| student_t(3, 0, 2.5) | sds | s(Dev_Yr, k = 3, m = 2) | 0 | (vectorized) |
解决方案
在brms中,GAM的平滑项s(Dev_Yr)会被拆分为两类参数,需要分别设置先验:
1. 平滑基函数的系数(对应sDev_Yr_1)
sDev_Yr_1是平滑项s(Dev_Yr, k=3, m=2)的基函数系数(因k=3,实际包含多个系数,摘要中显示的是整体汇总值)。设置先验时需结合Dev_Yr的取值范围调整先验尺度:
- 如果
Dev_Yr取值范围大,可适当放大先验标准差,避免过度约束;反之则缩小。 - 示例:给
sDev_Yr_1设置正态先验:
set_prior("normal(0, 5)", class = "b", coef = "sDev_Yr_1")
2. 平滑项的标准差(对应sds(sDev_Yr_1))
这个参数控制整个平滑曲线的波动幅度,设置合适的先验可避免曲线过度拟合或欠拟合:
- 示例:给平滑项标准差设置半学生t先验:
set_prior("student_t(3, 0, 3)", class = "sds", coef = "s(Dev_Yr, k = 3, m = 2)")
完整先验设置示例
将上述先验与已有先验整合:
GAM_prior <- c( # 平滑系数sDev_Yr_1的非平坦先验 set_prior("normal(0, 5)", class = "b", coef = "sDev_Yr_1"), # 平滑项标准差的先验 set_prior("student_t(3, 0, 3)", class = "sds", coef = "s(Dev_Yr, k = 3, m = 2)"), # 原有其他先验 set_prior("normal(0.02, 0.01)", class = "b", coef = "Cal_Yr_Time"), set_prior("normal(1, 0.95)", class = "b", coef = "Dev_Yr_1_Factor2"), set_prior("student_t(3, 0.1, 0.05)", class = "b", coef = "Dev_Yr_10_Spline", dpar = "sigma"), set_prior("normal(-0.1, 0.05)", class = "b", coef = "Dev_Yr_6_Cap", dpar = "sigma"), set_prior("normal(0.2, 0.1)", class = "b", coef = "Intercept", dpar = "sigma") )
验证先验设置
运行prior_summary(Model_GAM)可以检查先验是否正确应用,确保sDev_Yr_1的先验已从默认平坦改为自定义的非平坦先验。
发散转移问题处理
针对模型出现的发散转移警告,可尝试将adapt_delta提高至0.995:
control = list(adapt_delta = .995 )
内容的提问来源于stack exchange,提问作者Michael Larsen
相关产品推荐
相关产品推荐

