R语言中加权自助法(Weighted Bootstrap)实现正确性验证
加权自助法的理解与代码修正
一、你的核心理解是对的
加权自助法的核心逻辑确实是给每个观测值分配对应的选中概率,让重要性高的观测更易被抽到,你的这个认知没问题。
二、代码里的两个关键错误
你的实现存在两处明显问题,会导致结果不符合加权自助法的预期:
1. 自助样本的均值计算错用了原始权重
每次抽样得到bootstrap_sample后,你用原始权重去计算加权均值是错误的。因为有放回抽样的过程已经通过每个点的出现次数体现了权重:权重高的点更可能被多次抽中,它的“权重”就是在样本里的出现次数,此时只需要计算这个自助样本的普通均值就行。
比如原始数据里权重最高的3,要是在一次自助抽样里被抽中2次,那它对本次均值的贡献就是3*2,不需要再乘原始的0.3。
2. (小细节)权重无需强制和为1
sample函数的prob参数会自动对输入的权重做归一化处理,所以你不用特意把权重调整到和为1,当然你示例里的权重是合法的,只是这个限制没必要。
三、修正后的代码
基础版本(直观易懂)
# 计算普通均值即可,自助样本的抽样权重已通过出现次数体现 sample_mean <- function(x) { mean(x) } weighted_bootstrap <- function(data, weights, R) { estimates <- numeric(R) n <- length(data) for (i in seq_len(R)) { # 按权重有放回抽取n个样本 bootstrap_sample <- sample(data, size = n, replace = TRUE, prob = weights) # 计算该样本的普通均值 estimates[i] <- sample_mean(bootstrap_sample) } estimates }
高效版本(适合大数据集)
如果数据集很大,生成重复的样本向量会占用较多内存,直接计算每个原始点的抽样次数再算加权均值更高效:
weighted_bootstrap_efficient <- function(data, weights, R) { estimates <- numeric(R) n <- length(data) for (i in seq_len(R)) { # 生成每个原始点的抽样次数(服从多项分布) counts <- rmultinom(1, size = n, prob = weights) # 用抽样次数作为权重计算均值 estimates[i] <- sum(data * counts) / n } estimates }
四、测试示例
用你提供的数据测试修正后的代码:
data <- c(1, 2, 3, 4, 5) weights <- c(0.1, 0.2, 0.3, 0.2, 0.2) R <- 1000 # 基础版本 estimates <- weighted_bootstrap(data, weights, R) hist(estimates, main = "加权自助法均值分布", xlab = "均值") # 高效版本(结果与基础版一致) estimates_eff <- weighted_bootstrap_efficient(data, weights, R) hist(estimates_eff, main = "高效版加权自助法均值分布", xlab = "均值")
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

