rstan运行贝叶斯模型时缺失值NA的处理位置与方案咨询
问题背景
我构建了包含数据、模型结构、参数、似然函数等典型组件的贝叶斯线性回归模型,相关依赖包加载与模型定义代码如下:
library(ggplot2) #library (ggedit) library(plyr) library(StanHeaders) library(rstan) # Equation (1) for(i in 1:N){ alphaC_P[i] ~ normal ((alphaC_A[Date[i]]) * (1- (F_T[Date[i]])) + alphaC_T[i] * (F_T[Date[i]]), sigma_C); }
受内存需求限制,我在计算集群上运行该分析:首先整理传入模型的元素列表(对应代码段Equation (2):mylist <- list()),随后在集群上调用rstan接口执行贝叶斯推断,模型调用代码如下:
# Equation (3) rstan::stan(file=args[2], data= mylist, cores=12, warmup= 48000, iter= 50000, chains= 4, seed = 14) # file=args[2] = Bayesian model
当前使用的数据集存在缺失值NA,咨询两个问题:
- 缺失值的省略/忽略/剔除处理逻辑应当添加在哪个环节?是模型定义段(Equation 1)、数据列表准备段(Equation 2)还是模型调用段(Equation 3)?
- 针对该建模场景,缺失值应当采用省略、忽略还是剔除的处理方案?
解答
关于处理环节的选择
缺失值处理逻辑必须放在Equation (2)即数据列表准备阶段,原因如下:
- Stan本身不支持传入带NA值的数据集,若直接将带缺失值的数据存入
mylist传入模型,程序会在初始化阶段直接报错终止,根本不会进入后续的似然计算或采样流程。 - 模型定义段(Equation 1)仅负责声明参数、定义先验分布与似然函数的数学关系,不承担原始数据清洗、缺失值处理的职能。
- 模型调用段(Equation 3)仅负责将准备完成的合规数据传入编译好的模型、设置采样参数,也不具备数据预处理的功能。
- 如果你计划采用模型内插补的方案(即把缺失值作为待估计参数纳入贝叶斯推断),也需要在数据准备阶段先标记缺失值位置、拆分已观测数据,不能直接传入NA值。
关于处理方案的选择
不存在通用的最优方案,需要结合缺失值的生成机制判断,适配你当前rstan建模场景的选择逻辑如下:
- 若缺失值为完全随机生成(例如仪器偶发漏采、无规律的记录丢失),且缺失样本占总样本比例低于5%:直接在数据准备阶段剔除带缺失值的样本即可,对结果偏差的影响极小,实现成本最低。
- 若缺失比例在5%~20%区间,且缺失值的出现和你已观测到的协变量相关(例如某一日期的
F_T值缺失和当日气温、采样点位等已掌握的变量有关):不建议直接剔除样本,优先在数据准备阶段完成多重插补后再传入模型,也可以在Stan模型中将缺失值声明为待估计参数做联合插补,避免样本损失导致的统计效力下降。 - 若缺失值不是随机生成(例如
alphaC_T数值过高/过低时才会出现记录缺失):无论缺失比例高低都不能直接剔除,必须在模型中对缺失机制做显式建模,否则结果会存在严重的选择偏差。
注意:Stan和rstan没有内置自动忽略/删除缺失值的功能,不要指望程序自动跳过NA值运行,只要输入数据包含NA就会直接触发报错。
内容的提问来源于stack exchange,提问作者Kirds
相关产品推荐
相关产品推荐

