第 22 章 模拟实验设计与课程项目

本章是全书的收束。计算统计课程不仅要求学生会调用函数,还要求学生能设计一个可复现的计算实验,用模拟或真实数据回答一个统计问题。模拟实验的价值在于:我们知道真实数据生成过程,因此可以检查估计方法、算法和诊断是否按预期表现。

22.1 模拟实验的基本要素

一个完整的模拟实验通常包括以下要素:

  1. 研究问题:要比较什么方法,或评估什么性质?
  2. 数据生成过程:明确随机变量如何生成,真实参数是什么。
  3. 实验因素:样本量、噪声水平、变量相关性、缺失比例等。
  4. 重复次数:每个设定下重复模拟多少次。
  5. 评价指标:偏差、方差、均方误差、覆盖率、预测误差、计算时间等。
  6. 结果汇总:用表格或图形比较不同方法。
  7. 可复现性:设置随机种子,保留代码和参数设定。

设某方法在第 \(r\) 次模拟中得到估计量 \(\hat\theta^{(r)}\),真实值为 \(\theta\)。模拟偏差估计为

\[ \widehat{\operatorname{Bias}} = \frac{1}{R}\sum_{r=1}^R \hat\theta^{(r)}-\theta. \]

均方误差估计为

\[ \widehat{\operatorname{MSE}} = \frac{1}{R}\sum_{r=1}^R(\hat\theta^{(r)}-\theta)^2. \]

这里 \(R\) 是重复次数。\(R\) 越大,模拟结果越稳定,但计算成本也越高。

22.2 示例:多重共线性下 OLS 与 Ridge 的比较

我们设计一个小实验,比较普通最小二乘和 Ridge 回归在解释变量高度相关时的预测表现。数据生成过程为

\[ Y=1+X_1+X_2+\varepsilon, \]

其中 \(X_1\)\(X_2\) 的相关性由 \(\rho\) 控制。

ridge_fit_simple <- function(X, y, lambda) {
  Xs <- scale(X)
  yc <- y - mean(y)
  center <- attr(Xs, "scaled:center")
  scale_x <- attr(Xs, "scaled:scale")

  beta_scaled <- solve(crossprod(Xs) + lambda * diag(ncol(Xs)),
                       crossprod(Xs, yc))
  beta <- as.vector(beta_scaled) / scale_x
  intercept <- mean(y) - sum(center * beta)
  list(intercept = intercept, beta = beta)
}

one_run <- function(n = 80, rho = 0.9, lambda = 5) {
  x1 <- rnorm(n)
  x2 <- rho * x1 + sqrt(1 - rho^2) * rnorm(n)
  X <- cbind(x1, x2)
  y <- 1 + x1 + x2 + rnorm(n, sd = 1.5)

  x1_new <- rnorm(500)
  x2_new <- rho * x1_new + sqrt(1 - rho^2) * rnorm(500)
  X_new <- cbind(x1_new, x2_new)
  y_new <- 1 + x1_new + x2_new + rnorm(500, sd = 1.5)

  fit_ols <- lm(y ~ X)
  pred_ols <- cbind(1, X_new) %*% coef(fit_ols)

  fit_ridge <- ridge_fit_simple(X, y, lambda)
  pred_ridge <- fit_ridge$intercept + X_new %*% fit_ridge$beta

  c(ols_mse = mean((y_new - pred_ols)^2),
    ridge_mse = mean((y_new - pred_ridge)^2))
}

现在改变样本量和相关系数,重复模拟。

set.seed(2026)
settings <- expand.grid(n = c(40, 120),
                        rho = c(0.3, 0.9))
R <- 200
result <- data.frame()

for (i in seq_len(nrow(settings))) {
  out <- replicate(R, one_run(n = settings$n[i],
                             rho = settings$rho[i],
                             lambda = 5))
  result <- rbind(result, data.frame(
    n = settings$n[i],
    rho = settings$rho[i],
    method = c("OLS", "Ridge"),
    mse = rowMeans(out)
  ))
}

result
#>              n rho method   mse
#> ols_mse     40 0.3    OLS 2.447
#> ridge_mse   40 0.3  Ridge 2.435
#> ols_mse1   120 0.3    OLS 2.296
#> ridge_mse1 120 0.3  Ridge 2.294
#> ols_mse2    40 0.9    OLS 2.424
#> ridge_mse2  40 0.9  Ridge 2.379
#> ols_mse3   120 0.9    OLS 2.293
#> ridge_mse3 120 0.9  Ridge 2.284

这个实验展示了模拟研究的基本逻辑:我们不是只运行一次,而是在多个设定下重复运行,比较平均表现。如果 \(\rho\) 较高、样本量较小,Ridge 可能因为降低方差而获得更好预测表现。

22.3 课程项目方向

以下项目都可以使用模拟数据完成,也可以在教师允许并注明来源的情况下使用公开数据。

  1. 收入不平等指标的 Bootstrap 评估
    设计一个模拟收入分布,计算均值、中位数、贫困率或基尼系数,用 Bootstrap 评估不确定性。

  2. 消费函数的模型选择与预测
    模拟家庭收入、就业和消费数据,比较线性、对数和正则化模型的预测表现。

  3. 违约概率预测
    模拟企业或个人信用数据,比较逻辑回归、正则化逻辑回归和交叉验证指标。

  4. 缺失数据与 EM 算法
    构造不同缺失机制,比较完整案例分析、简单插补和 EM 估计的偏差。

  5. MCMC 后验计算实验
    对一个一维或二维贝叶斯模型,比较网格法、Laplace 近似和 MCMC 的结果。

  6. 抽样设计模拟
    构造有限总体,比较简单随机抽样、分层抽样和不同样本量下估计量的方差。

22.4 项目报告规范

课程项目报告建议包括以下部分:

  1. 问题背景:说明要研究的经济统计问题和核心指标。
  2. 数据说明:若为模拟数据,写清数据生成过程;若为真实数据,注明来源和变量含义。
  3. 方法说明:写出模型、算法和评价指标,不只贴代码。
  4. 计算实现:提供可运行 R 代码,设置随机种子,避免依赖本地绝对路径。
  5. 结果展示:用表格或图形汇总结果,避免只输出原始控制台结果。
  6. 诊断与稳健性:讨论收敛、模拟误差、交叉验证波动或先验敏感性。
  7. 结论解释:回到经济统计问题,用清楚语言解释发现和局限。

22.5 常见问题

学生项目中常见问题包括:

  1. 数据生成过程没有写清,导致别人无法复现;
  2. 只运行一次模拟,却得出一般性结论;
  3. 把训练误差当作预测表现;
  4. 只报告系数显著性,不解释经济含义;
  5. 使用真实数据但没有说明来源;
  6. 代码依赖个人电脑路径或未安装包;
  7. 图表没有标题、单位或变量说明。

这些问题都不是小细节。计算统计强调可复现、可检查、可解释,报告规范是统计工作的一部分。

22.6 本章小结

模拟实验是理解计算统计方法的重要方式。一个好的模拟实验应有明确问题、透明的数据生成过程、合理的实验因素、足够重复次数和清楚的评价指标。课程项目的目标不是堆砌复杂方法,而是完成一个从问题、数据、算法、诊断到解释的闭环。

22.7 练习

  1. 在 OLS 与 Ridge 模拟中,把误差标准差从 1.5 改为 3,观察结果变化。
  2. 将重复次数 \(R\) 从 50 增加到 1000,比较模拟结果稳定性。
  3. 设计一个比较 Bootstrap 百分位数区间覆盖率的模拟实验。
  4. 为一个你感兴趣的经济统计主题写出项目题目、数据生成过程和评价指标。