第 21 章 经济统计综合案例

前面章节分别介绍了数值计算、优化、随机模拟、重采样、模型计算和贝叶斯计算。本章用一个完整的模拟经济统计案例把这些内容串起来。案例主题是家庭收入与消费支出分析。我们关心三个问题:

  1. 家庭收入和就业状态如何影响消费支出?
  2. 消费收入比这一统计指标的不确定性有多大?
  3. 不同模型在预测消费支出时表现如何?

本章所有数据均为模拟数据,不对应任何真实调查来源。这样做的好处是数据生成过程透明,便于教学中检查模型和算法是否按预期工作。

21.1 数据生成与变量说明

设家庭所在地区分为东部、中部和西部。收入服从右偏分布,就业状态与收入相关,消费支出由收入、就业和地区共同决定,并加入随机扰动。

set.seed(2026)
n <- 800
region <- sample(c("东部", "中部", "西部"), n, replace = TRUE,
                 prob = c(0.42, 0.32, 0.26))
region_effect <- ifelse(region == "东部", 0.20,
                        ifelse(region == "中部", 0, -0.15))

income <- rlnorm(n, meanlog = log(8) + region_effect, sdlog = 0.55)
employed <- rbinom(n, 1, prob = plogis(-0.5 + 0.18 * income))
consumption <- 1.4 + 0.58 * income + 0.75 * employed +
  ifelse(region == "东部", 0.5, ifelse(region == "西部", -0.3, 0)) +
  rnorm(n, sd = 1.6)
consumption <- pmax(consumption, 0.2)

survey <- data.frame(region, income, employed, consumption)
head(survey)
#>             region income employed consumption
#> 1 <U+4E2D><U+90E8> 16.689        1      10.552
#> 2 <U+4E2D><U+90E8> 10.842        1      10.244
#> 3 <U+4E1C><U+90E8>  5.465        0       4.156
#> 4 <U+4E1C><U+90E8>  8.801        1       9.603
#> 5 <U+4E2D><U+90E8>  4.852        1       3.904
#> 6 <U+4E1C><U+90E8>  3.251        0       5.749

变量含义如下:

  1. region:家庭所在地区;
  2. income:家庭收入,单位可以理解为万元;
  3. employed:家庭主要劳动力是否就业,1 表示就业;
  4. consumption:家庭消费支出,单位可以理解为万元。

21.2 数据检查与预处理

经济统计数据常见问题包括缺失值、极端值和变量尺度差异。为了贴近实际工作流,我们人为制造少量缺失,并进行简单处理。

set.seed(1)
miss_id <- sample(seq_len(n), size = round(0.06 * n))
survey$income_obs <- survey$income
survey$income_obs[miss_id] <- NA

c(missing_rate = mean(is.na(survey$income_obs)),
  observed_mean = mean(survey$income_obs, na.rm = TRUE),
  complete_mean = mean(survey$income))
#>  missing_rate observed_mean complete_mean 
#>          0.06         10.14         10.06

这里缺失是随机制造的,因此完整样本均值和观测样本均值差异不大。真实调查中,如果高收入家庭更倾向于不报告收入,简单删除缺失样本会产生偏差。此处为了聚焦计算流程,使用完整案例分析:

dat <- survey[complete.cases(survey[, c("income_obs", "consumption", "employed", "region")]), ]
dat$log_income <- log(dat$income_obs)

summary(dat[, c("income_obs", "log_income", "consumption")])
#>    income_obs      log_income     consumption   
#>  Min.   : 1.29   Min.   :0.253   Min.   : 0.20  
#>  1st Qu.: 5.83   1st Qu.:1.764   1st Qu.: 5.11  
#>  Median : 8.70   Median :2.164   Median : 7.17  
#>  Mean   :10.14   Mean   :2.152   Mean   : 7.95  
#>  3rd Qu.:12.29   3rd Qu.:2.509   3rd Qu.: 9.80  
#>  Max.   :63.98   Max.   :4.159   Max.   :39.33

收入右偏,因此建立模型时同时考虑收入水平和对数收入两种设定。

21.3 描述性统计指标

先计算平均收入、平均消费和消费收入比:

\[ R=\frac{\bar C}{\bar Y}, \]

其中 \(\bar C\) 为平均消费,\(\bar Y\) 为平均收入。

ratio_stat <- function(d) mean(d$consumption) / mean(d$income_obs)

c(mean_income = mean(dat$income_obs),
  mean_consumption = mean(dat$consumption),
  consumption_income_ratio = ratio_stat(dat))
#>              mean_income         mean_consumption consumption_income_ratio 
#>                  10.1367                   7.9506                   0.7843

aggregate(cbind(income_obs, consumption) ~ region, data = dat, mean)
#>             region income_obs consumption
#> 1 <U+4E1C><U+90E8>     11.496       9.191
#> 2 <U+4E2D><U+90E8>      9.737       7.493
#> 3 <U+897F><U+90E8>      8.152       6.275

描述性统计不是建模的替代品,但它能帮助我们理解变量尺度、组间差异和后续模型是否合理。

21.4 Bootstrap 评估指标不确定性

消费收入比是一个比率统计量,其标准误不如样本均值那样直观。我们使用非参数 Bootstrap 评估其不确定性。

set.seed(2)
B <- 1000
boot_ratio <- numeric(B)
n_dat <- nrow(dat)

for (b in seq_len(B)) {
  id <- sample(seq_len(n_dat), size = n_dat, replace = TRUE)
  boot_ratio[b] <- ratio_stat(dat[id, ])
}

c(estimate = ratio_stat(dat),
  boot_se = sd(boot_ratio),
  q025 = quantile(boot_ratio, 0.025),
  q975 = quantile(boot_ratio, 0.975))
#>   estimate    boot_se  q025.2.5% q975.97.5% 
#>   0.784334   0.007256   0.770653   0.799043

这个结果回答的是:如果当前样本可视为总体的代表性样本,那么消费收入比的抽样不确定性大约有多大。

21.5 回归模型设定与计算

考虑两个候选模型:

\[ M_1:\quad C_i=\beta_0+\beta_1Y_i+\beta_2E_i+\gamma_{r(i)}+\varepsilon_i, \]

\[ M_2:\quad C_i=\beta_0+\beta_1\log Y_i+\beta_2E_i+\gamma_{r(i)}+\varepsilon_i. \]

其中 \(C_i\) 是消费支出,\(Y_i\) 是收入,\(E_i\) 是就业状态,\(\gamma_{r(i)}\) 是地区效应。

fit_level <- lm(consumption ~ income_obs + employed + region, data = dat)
fit_log <- lm(consumption ~ log_income + employed + region, data = dat)

summary(fit_level)$coefficients
#>                        Estimate Std. Error t value   Pr(>|t|)
#> (Intercept)              2.0021   0.147377  13.585  1.007e-37
#> income_obs               0.5819   0.009107  63.896 5.550e-305
#> employed                 0.6601   0.130109   5.073  4.934e-07
#> region<U+4E2D><U+90E8>  -0.6369   0.127463  -4.997  7.254e-07
#> region<U+897F><U+90E8>  -0.9503   0.145482  -6.532  1.200e-10
summary(fit_log)$coefficients
#>                        Estimate Std. Error t value   Pr(>|t|)
#> (Intercept)             -4.9176     0.3610 -13.621  6.731e-38
#> log_income               5.9391     0.1557  38.156 1.354e-177
#> employed                 0.6495     0.1950   3.331  9.077e-04
#> region<U+4E2D><U+90E8>  -0.6107     0.1891  -3.229  1.296e-03
#> region<U+897F><U+90E8>  -0.7811     0.2177  -3.588  3.545e-04

c(AIC_level = AIC(fit_level),
  AIC_log = AIC(fit_log))
#> AIC_level   AIC_log 
#>      2762      3353

如果使用收入水平,收入系数可以解释为收入增加 1 万元时消费支出的平均变化;如果使用对数收入,系数表示收入按比例变化时消费支出的变化。模型选择不仅取决于 AIC,也取决于解释目标。

21.6 交叉验证预测评估

下面使用 5 折交叉验证比较两个模型的预测均方误差。

cv_lm_case <- function(formula, data, K = 5) {
  n <- nrow(data)
  fold <- sample(rep(seq_len(K), length.out = n))
  mse <- numeric(K)

  for (k in seq_len(K)) {
    train <- data[fold != k, ]
    valid <- data[fold == k, ]
    fit <- lm(formula, data = train)
    pred <- predict(fit, newdata = valid)
    mse[k] <- mean((valid$consumption - pred)^2)
  }
  mean(mse)
}

set.seed(3)
c(level_model = cv_lm_case(consumption ~ income_obs + employed + region, dat),
  log_model = cv_lm_case(consumption ~ log_income + employed + region, dat))
#> level_model   log_model 
#>       2.304       5.108

如果预测是主要目标,应重视交叉验证结果;如果政策解释是主要目标,应同时考虑变量形式是否符合经济含义。

21.7 结果解释与报告

一份简洁的结果报告可以按以下顺序组织:

  1. 数据说明:本例为模拟家庭调查数据,包含收入、就业、地区和消费支出。
  2. 描述性发现:报告平均收入、平均消费和地区差异。
  3. 指标不确定性:用 Bootstrap 给出消费收入比的标准误和区间。
  4. 模型设定:说明为什么比较收入水平和对数收入模型。
  5. 计算诊断:报告样本量、缺失处理、模型比较指标和交叉验证误差。
  6. 经济解释:把系数和预测结果翻译成收入、就业与消费之间的关系。
  7. 局限性:说明数据为模拟数据,真实研究还需要调查设计、权重、缺失机制和因果识别。

21.8 本章小结

本章通过模拟家庭调查案例串联了全书多个主题:数据生成与预处理、描述性指标、Bootstrap 不确定性评估、线性模型计算、模型比较和交叉验证。完整统计分析不是某个函数调用,而是从数据、模型、算法、诊断到解释的连续流程。

21.9 练习

  1. 把缺失比例改为 20%,比较完整案例分析结果的变化。
  2. 对平均收入而不是消费收入比做 Bootstrap,比较两者区间宽度。
  3. 在回归模型中加入收入平方项,比较 AIC 和交叉验证误差。
  4. 设计一个新的模拟变量,例如家庭人口数,并说明它可能如何影响消费支出。