在传统回归分析中,我们最熟悉的是最小二乘回归(OLS),它刻画的是自变量变化对因变量条件均值的影响。但现实世界中,很多问题并不只关心“平均水平”,而是更关心:
- 高风险人群是否受到更大影响?
- 弱势群体是否对某些因素更敏感?
- 自变量对分布尾部(如高血压人群、极端收入者、重症患者)的影响是否不同?
这正是分位数回归(Quantile Regression, QR)的用武之地。
一、什么是分位数回归?
分位数回归是一种用于建模条件分布不同分位点的方法。与普通回归建模条件均值不同,分位数回归直接建模:
QY(τ∣X=x) Q_Y(\tau \mid X = x)QY(τ∣X=x)
即在给定自变量X=xX = xX=x时,因变量YYY的第τ\tauτ分位数(如中位数、90%分位数等)。
例如:
- (τ\tauτ= 0.5 ):中位数回归;
- (τ\tauτ= 0.9 ):高分位(上尾)回归;
- (τ\tauτ= 0.1 ):低分位(下尾)回归。
二、分位数回归的数学定义
给定样本{(xi,yi)}i=1n\{(x_i, y_i)\}_{i=1}^n{(xi,yi)}i=1n,分位数回归通过最小化以下目标函数来估计参数:
β^(τ)=argminβ∑i=1nρτ(yi−xi⊤β), \hat{\beta}(\tau) = \arg\min_{\beta} \sum_{i=1}^n \rho_\tau\big(y_i - x_i^\top \beta\big),β^(τ)=argβmini=1∑nρτ(yi−xi⊤β),
其中损失函数ρτ(u)\rho_\tau(u)ρτ(u)被称为不对称绝对损失函数(check loss):
ρτ(u)={τu,u≥0,(τ−1)u,u<0. \rho_\tau(u) = \begin{cases} \tau u, & u \ge 0, \\ (\tau - 1)u, & u < 0. \end{cases}ρτ(u)={τu,(τ−1)u,u≥0,u<0.
当 (τ\tauτ= 0.5 ) 时,该模型退化为中位数回归(L1L1L1回归)。
可以看出为了让损失函数ρτ(u)\rho_\tau(u)ρτ(u)最小,(τ−1)u(\tau - 1)u(τ−1)u越小越好,也就是对yi−xi⊤βy_i - x_i^\top \betayi−xi⊤β(残差)施加τ−1\tau - 1τ−1权重后越小越好,残差符合正态分布,也就是把残差往τ−1\tau - 1τ−1分位逼进。
三、这里的“分位”到底是什么意思?(非常重要)
这是很多人对分位数回归最容易产生误解的地方。
❌ 错误理解:
“把人群按YYY排序后,取前 10%、中间 50%、后 10% 的人分别做回归。”
✅ 正确理解:
分位数回归建模的是:
在控制其他自变量处于同一水平的条件下,因变量YYY的条件分位数。
也就是说:
QY(τ∣X=x) Q_Y(\tau \mid X = x)QY(τ∣X=x)
不是总体分位,而是在给定协变量X=xX = xX=x的条件下,YYY的第τ\tauτ分位点。
你不是在对“人群分组”,而是在对:
“如果所有人的协变量都相同,结果变量在这个假想人群中的分布位置。”
做建模。
这一区别非常关键,因为它确保分位数回归估计的是净效应,而不是由混杂因素驱动的表面差异。
四、分位数回归在模型层面上做了什么?
OLS 回归建模的是:
E(Y∣X=x)=x⊤β E(Y \mid X = x) = x^\top \betaE(Y∣X=x)=x⊤β
而分位数回归建模的是:
QY(τ∣X=x)=x⊤β(τ) Q_Y(\tau \mid X = x) = x^\top \beta(\tau)QY(τ∣X=x)=x⊤β(τ)
也就是说,每一个分位数τ\tauτ都对应一组不同的回归系数β\betaβ(τ\tauτ) ,从而刻画自变量对因变量分布不同位置的影响差异。
五、分位数回归的意义:为什么要用它?
1. 揭示异质性效应
OLS 只能告诉你“平均影响”,但现实中影响往往具有异质性:
- 一个药物对轻症患者作用小,对重症患者作用大;
- 教育对低收入群体影响大,对高收入群体影响小。
分位数回归可以显示这种效应随分位点变化的模式。
2. 对异常值更稳健
由于使用的是绝对损失而非平方损失,分位数回归对极端值(outliers)不敏感,尤其是中位数回归(τ\tauτ= 0.5)。
3. 可用于刻画整个条件分布
通过对多个分位点(如τ\tauτ= 0.1, 0.25, 0.5, 0.75, 0.9)建模,可以近似重构:
FY∣X(y∣x) F_{Y \mid X}(y \mid x)FY∣X(y∣x)
从而获得比均值回归更丰富的信息。
六、分位数回归斜率的意义是什么?
在 OLS 中,斜率βj\beta_jβj表示:
自变量XjX_jXj增加一个单位,因变量的条件均值增加βj\beta_jβj。
而在分位数回归中,斜率βj(τ)\beta_j(\tau)βj(τ)表示:
在控制其他变量不变的情况下,自变量XjX_jXj增加一个单位,因变量的第τ\tauτ条件分位数增加βj(τ)\beta_j(\tau)βj(τ)。
换句话说:
- 如果βj(0.9)>βj(0.5)\beta_j(0.9) > \beta_j(0.5)βj(0.9)>βj(0.5),说明该变量对高值人群的影响更大;
- 如果βj(0.1)≈0\beta_j(0.1) \approx 0βj(0.1)≈0,说明该变量对低值人群几乎没有影响。
七、一个直观例子
假设我们研究空气污染(PM2.5)对肺功能(FEV₁)的影响:
- OLS 回归可能发现:PM2.5 每增加 10 μg/m³,FEV₁ 平均下降 30 mL。
- 分位数回归可能发现:
- 在第 10 分位:下降 10 mL;
- 在第 50 分位:下降 30 mL;
- 在第 90 分位:下降 60 mL。
这说明:空气污染对肺功能较差的人群影响更大,这是均值回归无法揭示的关键信息。
八、分位数回归与异方差的关系
OLS 在存在异方差时效率下降,而分位数回归天然允许:
Var(Y∣X=x) 随 x 变化 \text{Var}(Y \mid X = x) \text{ 随 } x \text{ 变化}Var(Y∣X=x)随x变化
通过观察不同分位数回归线的“展开”或“收缩”,可以直观判断条件分布是否存在异方差或尾部结构变化。
九、总结一句话
- OLS 回归:告诉你“平均会发生什么”;
- 分位数回归:告诉你“在相同条件下,不同人群位置会发生什么”。
如果你的研究关心:
- 弱势人群、
- 高风险个体、
- 极端结局、
- 或效应异质性,
那么分位数回归不是可选项,而是必选工具。
R 实践
模拟数据
# 加载必要的包 rm(list = ls()) library(quantreg) library(ggplot2) # 模拟数据 set.seed(42) n <- 500 education <- rnorm(n, mean = 12, sd = 2) income <- 2000 + 300 * education + rnorm(n, mean = 0, sd = 500) * ifelse(runif(n) > 0.8, 10, 1) # 引入异常值 data <- data.frame(education, income) # 绘制散点图 ggplot(data, aes(x = education, y = income)) + geom_point(alpha = 0.5) + labs(title = "Scatter Plot of Income vs. Education", x = "Years of Education", y = "Income")传统线性回归
lm_model <- lm(income ~ education, data = data) summary(lm_model)分位数回归
qr_model <- rq(income ~ education, tau = 0.5, data = data) summary(qr_model)多分位点回归
qr_multi <- rq(income ~ education, tau = c(0.25, 0.5, 0.75), data = data) summary(qr_multi)可视化
# 加载必要包 library(ggplot2) library(quantreg) # 生成样本数据 set.seed(123) n <- 300 education <- rnorm(n, mean = 12, sd = 2) # 教育年限 income <- 5000 + 2000 * education + rnorm(n, sd = 5000) # 收入 data <- data.frame(education, income) # 拟合分位数回归 qr_25 <- rq(income ~ education, tau = 0.25, data = data) # 25% 分位 qr_50 <- rq(income ~ education, tau = 0.5, data = data) # 中位数回归 qr_75 <- rq(income ~ education, tau = 0.75, data = data) # 75% 分位 # 提取系数 coef_25 <- coef(qr_25) coef_50 <- coef(qr_50) coef_75 <- coef(qr_75) # 绘图 ggplot(data, aes(x = education, y = income)) + geom_point(alpha = 0.5, color = "grey50") + # 散点图 # 添加分位数回归线 geom_abline(intercept = coef_25[1], slope = coef_25[2], color = "red", linewidth = 1.2, linetype = "solid", show.legend = TRUE) + geom_abline(intercept = coef_50[1], slope = coef_50[2], color = "green", linewidth = 1.2, linetype = "solid", show.legend = TRUE) + geom_abline(intercept = coef_75[1], slope = coef_75[2], color = "blue", linewidth = 1.2, linetype = "solid", show.legend = TRUE) + # 添加注释 annotate("text", x = 10, y = max(data$income) * 0.9, label = "25th Percentile", color = "red", size = 4) + annotate("text", x = 10, y = max(data$income) * 0.8, label = "50th Percentile (Median)", color = "green", size = 4) + annotate("text", x = 10, y = max(data$income) * 0.7, label = "75th Percentile", color = "blue", size = 4) + # 主题设置 labs(title = "Quantile Regression Visualization", x = "Years of Education", y = "Income") + theme_minimal()