为何R语言ecdf函数对混合均匀分布CDF的逼近效果差?
混合均匀分布ECDF不收敛的原因分析
核心问题是你没有正确从目标混合均匀分布中抽取样本。ecdf()函数本身是可靠的——根据格里文科-坎泰利定理,只要样本严格来自目标分布,随着样本量增大,ECDF必然依概率收敛到真实CDF。你的情况显然是样本生成逻辑错误,导致生成的样本根本不属于目标分布,自然无法逼近真实CDF。
目标分布的正确抽样逻辑
你的目标分布是两个均匀分布的等权重混合:
- 分量1:$U(-1, 2)$,权重1/2
- 分量2:$U(0, 1)$,权重1/2
正确的抽样步骤必须先按权重选择分量,再从选中的分量中抽取样本:
- 生成伯努利变量(概率0.5选分量1,0.5选分量2)
- 根据选中的分量,从对应均匀分布中抽取样本
正确抽样的R代码示例
set.seed(123) n <- 10000 # 按权重选择分量 component <- sample(c(1, 2), size = n, replace = TRUE, prob = c(0.5, 0.5)) # 生成符合目标分布的样本 x <- ifelse(component == 1, runif(n, -1, 2), runif(n, 0, 1)) # 计算ECDF ecdf_approx <- ecdf(x) # 定义真实CDF true_cdf <- function(x) { dplyr::case_when( x < -1 ~ 0, x >= -1 & x < 0 ~ (x + 1)/(6), x >= 0 & x < 1 ~ 1/6 + (x)/2, x >= 1 & x < 2 ~ 1/6 + 1/2 + (x - 1)/6, x >= 2 ~ 1 ) } # 绘图对比 plot(ecdf_approx, main = "ECDF vs 真实CDF", col = "blue", lwd = 2) curve(true_cdf, from = -1.5, to = 2.5, add = TRUE, col = "red", lwd = 2, lty = 2) legend("bottomright", legend = c("ECDF", "真实CDF"), col = c("blue", "red"), lwd = 2, lty = c(1,2))
运行这段代码可以看到,样本量越大,ECDF越贴近真实CDF。
常见的抽样错误场景
- 错误地将两个均匀样本直接平均:比如
x <- (runif(n,-1,2) + runif(n,0,1))/2,这得到的是两个独立均匀变量的均值分布,和目标混合分布完全无关。 - 分量权重设置错误:比如用了非等权重的抽样概率,导致样本偏向某一个分量。
- 均匀分布参数写错:比如把
runif(n,-1,2)误写成runif(n,0,2),直接改变了第一个分量的分布范围。 - 样本拼接逻辑错误:比如直接把两个分布的样本拼接后截断,没有按权重控制样本比例。
结论
ecdf()函数本身不存在问题,只要修正样本生成逻辑,确保样本严格来自目标混合均匀分布,ECDF就会随着样本量增大收敛到真实CDF。
内容的提问来源于stack exchange,提问作者Smilia
相关产品推荐
相关产品推荐

