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

蒙特卡洛验证均匀分布样本和的中心极限定理:样本量变化无显著差异疑问

问题:蒙特卡洛模拟验证中心极限定理的疑惑

我尝试用蒙特卡洛模拟展示:当样本维度增大时,均匀分布样本的和趋近于正态分布。具体来说,设$X \sim U[2,3]$,$X_1,…,X_n$是来自X的独立同分布样本,$S = \sum_{1}^{n}(X_i)$,我希望通过蒙特卡洛模拟验证当n足够大时,S的分布近似服从正态分布(符合中心极限定理预测)。我关注的是$X_i$的和,而非均值的一般情况,想要展示随样本量n增加,S的分布更趋近正态。

但我遇到两个问题:

  • 增减蒙特卡洛次数会明显影响正态性的视觉表现
  • 样本量从10增至100时,分布的正态性没有显著差异,甚至n=10时已经能看到近似正态的分布

以下是我的最小可复现代码:

# 创建10000个服从U[2,3]的均匀分布样本
data <- runif(n=10000, min=2, max=3)
hist(data, col='steelblue', main='Histogram from the Uniform')

# 进行1000次蒙特卡洛模拟,每次取10个样本求和
sample10 <- c()
n = 1000
for (i in 1:n){
 sample10[i] = sum(sample(data, 10, replace=TRUE))
}
hist(sample10, col ='steelblue', main='Sample size = 10', prob=TRUE)
qqnorm(sample10); qqline(sample10)

# 增大单次模拟的样本量到100
sample100 <- c()
n = 1000
for (i in 1:n){
 sample100[i] = sum(sample(data, 100, replace=TRUE))
}
hist(sample100, col ='steelblue', main='Sample size = 100', prob=TRUE)
qqnorm(sample100); qqline(sample100)

请问我哪里出错了?


问题原因与改进方案

1. 蒙特卡洛次数影响表现的核心原因

你当前设置的蒙特卡洛次数(1000次)过少,导致模拟得到的sample10和sample100本身属于小样本,分布的随机性极强,所以增减次数会让直方图、QQ图的表现出现大幅波动。要稳定展示真实的分布形态,需要大幅提高蒙特卡洛次数(比如增加到10000次甚至更多),让模拟得到的和的样本量足够大,才能抵消随机波动,呈现稳定的分布特征。

2. n=10时已近似正态的原因

均匀分布是对称分布,中心极限定理对对称分布的收敛速度极快——对于均匀分布,n=10时和的分布已经非常接近正态分布,因此n从10提升到100时,正态性的提升在视觉上很难分辨。如果想要更直观看到收敛过程,可以:

  • 选择非对称的原始分布(比如指数分布),这类分布的收敛速度更慢,n从10到100的正态性差异会更明显
  • 对和进行标准化处理($Z = \frac{S - n\mu}{\sqrt{n\sigma^2}}$),把不同n的和转换到同一标准正态尺度下,更容易对比收敛程度:
    对于$X \sim U[2,3]$,$\mu = 2.5$,$\sigma^2 = \frac{(3-2)^2}{12} = \frac{1}{12}$,标准化后的统计量会随n增大更贴近标准正态分布,QQ图的拟合效果差异会更清晰

3. 代码优化点

  • 无需预先生成大样本data再反复抽样,直接在模拟中用runif生成样本求和,效率更高且避免重复抽样的潜在偏差
  • 用replicate替代循环,代码更简洁高效
  • 添加理论正态分布曲线作为参考,直观对比拟合程度

改进后的示例代码:

# 定义均匀分布的参数
mu <- 2.5
sigma_sq <- 1/12
mc_times <- 10000  # 提高蒙特卡洛次数至10000

# n=10的模拟与可视化
n10 <- 10
sum_n10 <- replicate(mc_times, sum(runif(n10, 2, 3)))
z_n10 <- (sum_n10 - n10*mu)/sqrt(n10*sigma_sq)

par(mfrow=c(2,2))
hist(sum_n10, col='steelblue', main='n=10: 和的分布', prob=TRUE)
curve(dnorm(x, mean=n10*mu, sd=sqrt(n10*sigma_sq)), add=TRUE, col='red', lwd=2)
qqnorm(z_n10, main='n=10: 标准化QQ图'); qqline(z_n10, col='red')

# n=100的模拟与可视化
n100 <- 100
sum_n100 <- replicate(mc_times, sum(runif(n100, 2, 3)))
z_n100 <- (sum_n100 - n100*mu)/sqrt(n100*sigma_sq)

hist(sum_n100, col='steelblue', main='n=100: 和的分布', prob=TRUE)
curve(dnorm(x, mean=n100*mu, sd=sqrt(n100*sigma_sq)), add=TRUE, col='red', lwd=2)
qqnorm(z_n100, main='n=100: 标准化QQ图'); qqline(z_n100, col='red')
par(mfrow=c(1,1))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 14:50:44