Python 分位数回归完全指南:从理论到实践

在这篇文章中,我们将深入探讨如何使用 Python 来执行分位数回归。如果你已经熟悉普通的线性回归(OLS),你会发现分位数回归是一个非常有价值的补充工具,它能帮助你揭示数据中隐藏的更深层次的模式。

为什么我们需要分位数回归?

作为数据科学家或分析师,我们经常使用线性回归来建模变量之间的关系。传统的普通最小二乘法(OLS)回归关注的是因变量的均值。也就是说,它试图找到一条线,使得所有数据点到这条线的垂直距离的平方和最小。

然而,在现实世界的很多场景中,仅关注“平均值”往往是不够的。例如:

  • 贫富差距分析:我们可能更关心高收入人群(第 90 百分位)和低收入人群(第 10 百分位)的差异,而不是平均收入。
  • 风险控制:在金融领域,我们可能更关心潜在的最坏情况(下行风险),这就需要关注较低的分位数。
  • 医疗研究:研究某种药物对不同体质患者的影响差异,而不仅仅是“平均”患者。

这就轮到分位数回归登场了。它不仅能够像 OLS 一样建模变量间的关系,还能让我们探索自变量如何影响因变量的分布形态,而不仅仅是中心趋势。

分位数回归的核心原理

简单来说,分位数回归是线性回归的扩展。如果我们把线性回归看作是计算 $Y = aX + b$ 中的均值,那么分位数回归就是在计算特定分位数(如第 50%、第 90%)下的 $Y$ 值。

在数学上,最小二乘法通过最小化平方误差来拟合,而分位数回归则是通过最小化“加权的绝对误差”来拟合。具体来说,它会根据预测值是高于还是低于实际分位数,赋予误差不同的权重。

准备工作:Python 库简介

在 Python 中,INLINECODE6a186320 库是实现分位数回归的主力军。虽然 INLINECODEaf1523c3 非常适合机器学习任务,但在进行统计推断和查看详细的回归摘要时,statsmodels 提供了更加类似 R 语言的专业体验。

步骤 1:构建并探索演示数据集

为了让你直观地理解,让我们从一个具体的例子入手。想象一下,我们正在研究汽车的总行驶距离与产生的排放量之间的关系。这不仅仅是想了解“平均”排放量,我们还想知道:对于那些里程数非常高的车,它们的排放量大概在什么水平?

下面的代码演示了如何创建一个包含 20 个样本的数据集。请注意,我们在生成数据时特意加入了一些随机噪声,并且噪声的大小随着距离的增加而增加,这模拟了现实世界中“距离越长,不确定性越大”的情况。

# Python 程序:创建演示数据集

# 导入必要的库
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt

# 设置随机种子以保证结果可复现
np.random.seed(0)

# 指定样本数量
rows = 20

# 构建“行驶距离”列,范围在 1 到 10 之间
# 这里的单位可以理解为“万公里”
Distance = np.random.uniform(1, 10, rows)

# 构建“排放量”列
# 这里的逻辑是:基础排放 20 + 距离的影响 + 随机噪声
# 注意:噪声的标准差与距离成正比,模拟 heteroscedasticity(异方差性)
Emission = 20 + np.random.normal(loc=0, scale=.25*Distance, size=20)

# 创建 DataFrame
df = pd.DataFrame({‘Distance‘: Distance, ‘Emission‘: Emission})

# 查看前几行数据
print(df.head())

输出示例:

    Distance    Emission
0  5.939322   22.218454
1  7.436704   19.618575
2  6.424870   20.502855
3  5.903949   18.739366
4  4.812893   16.928183

在这个阶段,我们通过简单的 df.head() 快速检查了数据结构。确保你的数据没有缺失值或异常的极端值是进行任何回归分析之前的好习惯。

步骤 2:估算分位数回归模型

现在,让我们进入核心环节。我们将构建一个模型,专门用来估算排放量的第 70 百分位

我们定义变量如下:

  • 自变量 ($X$):行驶距离
  • 因变量 ($Y$):排放量

我们的目标是回答:“如果有一辆车行驶了 $X$ 公里,那么有 70% 的概率,它的排放量会低于多少?”

以下是完整的建模代码,包含了模型拟合和结果解读:

# Python 程序:估算分位数回归

# 导入库(如果在同一环境中,这部分可省略,但为了完整性这里保留)
import numpy as np
import pandas as pd
import statsmodels.api as sm
import statsmodels.formula.api as smf

# 为了演示,我们重新生成一次数据(实际中你只需加载现有数据)
np.random.seed(0)
rows = 20
Distance = np.random.uniform(1, 10, rows)
# 这里稍微调整了公式,让数据更有趣:Emission = 40 + Distance + 噪声
Emission = 40 + Distance + np.random.normal(loc=0, scale=.25*Distance, size=20)

df = pd.DataFrame({‘Distance‘: Distance, ‘Emission‘: Emission})

# === 核心步骤:拟合模型 ===
# 使用 ‘smf.quantreg‘ 接口,类似于 R 语言的公式写法
# q=0.7 指定了我们要计算第 70 百分位
model = smf.quantreg(‘Emission ~ Distance‘, df).fit(q=0.7)

# 查看模型的详细摘要
print(model.summary())

结果解读:

运行上述代码后,你会看到一张详细的统计表。对于我们来说,最重要的是 P>

t

(p值) 和 coef (系数)。

如果 p 值小于 0.05,通常意味着该变量在统计上是显著的。在我们的模拟数据中,距离对排放量的影响通常是显著的。

根据输出,我们可以推导出回归方程。假设输出结果如下(数值可能因随机种子微小差异而不同):

> Estimated Equation (第 70 百分位):

> Emission_70 = 39.5647 + 1.3042 * Distance

这意味着:对于行驶距离为 $X$ 的汽车,我们可以预测其排放量的第 70 百分位数值约为 $39.56 + 1.30X$。换句话说,行驶距离每增加 1 个单位,高排放(第 70 百分位)的预期值增加约 1.30 个单位。

步骤 3:可视化分位数回归

“一图胜千言”。让我们通过图表来直观地理解第 70 百分位回归线在数据中的位置。我们还将绘制散点图,看看实际数据点是如何分布在这条线周围的。

# Python 程序:可视化分位数回归

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt

# 1. 准备数据
np.random.seed(0)
rows = 20
Distance = np.random.uniform(1, 10, rows)
Emission = 40 + Distance + np.random.normal(loc=0, scale=.25*Distance, size=20)
df = pd.DataFrame({‘Distance‘: Distance, ‘Emission‘: Emission})

# 2. 再次拟合模型(确保 q=0.7)
model = smf.quantreg(‘Emission ~ Distance‘, df).fit(q=0.7)

# 3. 开始绘图
fig, ax = plt.subplots(figsize=(10, 8))

# 计算回归线的 Y 值
# model.params[‘Intercept‘] 是截距
# model.params[‘Distance‘] 是斜率
y_pred = model.params[‘Intercept‘] + model.params[‘Distance‘] * Distance

# 绘制回归线 (黑色实线)
ax.plot(Distance, y_pred, color=‘black‘, linewidth=2, label=‘70th Percentile Fit‘)

# 绘制原始数据散点 (带透明度)
ax.scatter(Distance, Emission, alpha=.5, color=‘blue‘, s=50, label=‘Observed Data‘)

# 设置图表标签和标题
ax.set_xlabel(‘Distance Traveled (km)‘, fontsize=15)
ax.set_ylabel(‘Emission Generated‘, fontsize=15)
ax.set_title(‘Quantile Regression: 70th Percentile‘, fontsize=18)
ax.legend()
plt.grid(True, linestyle=‘--‘, alpha=0.6)

plt.show()

通过这张图,你可以清晰地看到回归线是如何穿过数据分布的上半部分的。它不像平均回归线那样试图平衡所有点,而是专注于捕捉高排放量的趋势。

进阶实战:比较不同分位数(0.1 vs 0.5 vs 0.9)

为了真正发挥分位数回归的威力,我们不能只看一条线。让我们对比一下低排放(10%)、中位数(50%)和高排放(90%)这三条线。这能帮我们发现数据中的“异方差性”——即随着距离增加,排放量的波动范围是否也在变大。

# Python 程序:多分位数对比分析

import numpy as np
import pandas as pd
import statsmodels.formula.api as smf
import matplotlib.pyplot as plt

# 1. 生成更具戏剧性的数据
np.random.seed(42)
rows = 200
Distance = np.random.uniform(1, 10, rows)
# 构造数据:随着距离增加,排放量的离散程度(标准差)显著增大
# 这创造了经典的“扇形”散点图,非常适合展示分位数回归的优势
Emission = 40 + Distance + np.random.normal(loc=0, scale=2.5*Distance, size=rows)

df = pd.DataFrame({‘Distance‘: Distance, ‘Emission‘: Emission})

# 2. 定义我们要探索的分位数
quantiles = [0.1, 0.5, 0.9]

# 3. 创建画布
fig, ax = plt.subplots(figsize=(12, 8))

# 4. 循环拟合并绘制每个分位数

# 先画出原始数据点
ax.scatter(Distance, Emission, alpha=.3, color=‘grey‘, label=‘Data Points‘)

# 使用不同的颜色和模型来拟合
for q in quantiles:
    # 拟合模型
    model = smf.quantreg(‘Emission ~ Distance‘, df).fit(q=q)
    
    # 预测值
    y_pred = model.params[‘Intercept‘] + model.params[‘Distance‘] * Distance
    
    # 绘制线条
    label_text = f‘q={q}‘
    ax.plot(Distance, y_pred, linewidth=2, label=label_text)

# 图表美化
ax.set_xlabel(‘Distance Traveled‘, fontsize=15)
ax.set_ylabel(‘Emission Generated‘, fontsize=15)
ax.set_title(‘Comparison of Quantile Regression Lines (0.1, 0.5, 0.9)‘, fontsize=18)
ax.legend()
plt.show()

代码深度解析:

在这个进阶示例中,你会看到一个明显的现象:第 0.9 分位数的回归线比第 0.1 分位数的回归线更陡峭。这意味着,对于行驶距离较长的汽车,高排放量的增长速度比低排放量的增长速度更快。如果仅使用普通的线性回归(均值),我们将无法捕捉到这种分布上的细微差异。

常见问题与解决方案

在实际操作中,你可能会遇到以下几个问题:

  • 收敛警告Maximum number of iterations exceeded.

* 原因:对于某些极端分位数(如 0.99 或 0.01)或非常小的数据集,算法可能难以找到最优解。

* 解决:尝试在 INLINECODE3e542bce 方法中增加 INLINECODEdbc331a6 参数,例如 fit(q=0.99, max_iter=1000)

  • 外推风险

* 分位数回归模型就像所有回归模型一样,不要在自变量范围之外(例如距离为 1000km,而训练数据最大为 10km)进行预测,结果可能不可靠。

总结与最佳实践

在这篇文章中,我们从零开始,学习了如何利用 Python 中的 statsmodels 库执行分位数回归。我们不仅编写了代码来估算单一分位数,还学会了如何通过对比不同分位数来深入洞察数据的分布特征。

关键要点:

  • 超越均值:分位数回归让你能够分析除了平均值之外的数据特征,这对于风险管理、不平等研究等领域至关重要。
  • R 语言风格的接口:使用 smf.quantreg(‘Y ~ X‘, data) 是一种非常直观且高效的建模方式。
  • 可视化是关键:一定要将你的回归线与散点图一起绘制,这是验证模型是否符合直观逻辑的最快方法。

我们鼓励你在自己的数据集上尝试这种方法。当你想了解“X 对 Y 的影响在不同水平下是否一致”时,分位数回归就是你手中最锋利的剑。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/17502.html
点赞
0.00 平均评分 (0% 分数) - 0