8.3 多元线性回归¶
本节学习目标
- 把简单线性回归推广到 多个自变量
- 掌握 矩阵形式 与正规方程
- 理解 偏回归系数 含义
- 警惕 多重共线性 (Multicollinearity)
8.3.1 房价 700 万差价里谁买的单¶
链家挂出来的房价像谜题:同一个城市,两套房一个 800 万一个 1500 万,差价 700 万到底是 面积 ** 、 学区 ** 、** 楼龄** 哪个买的单?经纪人嘴里能说出十条理由,老板想要的却是一个简单方程:
每个 \(\beta_j\) 应该回答一个具体问题:『 控制其他条件不变 ,每多 1 平米涨多少?是不是学区房真的多卖 8 千/平?楼龄一年掉多少?』上节的简单回归只能放一个 \(X\),搞不定这个买卖。 本节把 OLS 推广到多个变量,并直面三个新麻烦:偏系数怎么解释、整体显著怎么测、变量打架(多重共线)怎么办。
8.3.2 从拟合面到偏回归系数¶
一个 \(X\) 拟合一条直线,两个 \(X\) 拟合一张 平面 ** :每个数据点在 3D 空间里找到自己的高度(房价),最小二乘还在干同一件事——让所有点到这张平面的竖直距离平方和最小。 推广到 \(p\) 个 \(X\),平面变成 \(p\) 维的 ** 超平面 ,只是没法画了,但代数干活完全一样。
关键的直觉转变是『 偏系数 』:\(\beta_1\) 不是『面积单独看对房价的影响』,而是『 ** 学区与楼龄都不变** 时,面积每涨 1 平米的房价变化』。 这就是 partial 在做的事——它把其他变量先扣掉,只留下面积 独自 解释的那一部分变异。
下面的动画把这个『控制其他变量』变成可以看见的动作:拖动『固定 \(X_2\)』滑块,偏回归线整体平移但斜率不变——斜率才是 \(\beta_1\)。
动画末尾的提示已经预告了第二个直觉:当 \(X\) 之间互相高度相关(『大房子卧室多』),同一栋房子的『面积涨价』和『卧室涨价』就互相抢功劳——这种情况叫 多重共线性 ,下面会详谈。
8.3.3 设计矩阵与正规方程¶
把所有自变量打包成 设计矩阵 \(\mathbf{X} \in \mathbb{R}^{n \times (p+1)}\)(第一列全 1,对应截距),目标变量是 \(\mathbf{y} \in \mathbb{R}^n\),模型写作:
OLS 还是最小化残差平方和 \(\|\mathbf{y} - \mathbf{X}\boldsymbol{\beta}\|^2\),对 \(\boldsymbol{\beta}\) 求导置 0 解出 正规方程 :
要求 \(\mathbf{X}^\top \mathbf{X}\) 可逆 → 各列线性无关(无完全多重共线)。 一旦解出,每个 \(\hat{\beta}_j\) 都是『偏回归系数』:在所有其他 \(X\) 保持不变时,\(X_j\) 增 1 单位对 \(Y\) 的期望变化。
8.3.4 拟合优度:\(R^2\) 与调整 \(R^2\)¶
加变量时 \(R^2\) 永远不降(哪怕加进来的是噪声),所以单看 \(R^2\) 会被骗。 用自由度做修正:
加无关变量时 \(R^2_{\text{adj}}\) 会下降,模型对比要看 adj-\(R^2\)、AIC、BIC 才公平。
8.3.5 F 检验与 t 检验¶
整体 F 检验 :测试『所有 \(X\) 都没用』这个零假设:
显著 → 至少有一个 \(X\) 有效(但不知道是哪个)。
单系数 t 检验 :每个 \(\hat{\beta}_j\) 的 \(t = \hat{\beta}_j / \text{SE}(\hat{\beta}_j)\) 服从 \(t_{n-p-1}\),逐个判断显著性。 注意常出现『F 显著但每个 t 都不显著』的怪局——通常正是多重共线性在作祟。
8.3.6 多重共线性:诊断与修正¶
\(X\) 之间高度相关 → \((\mathbf{X}^\top \mathbf{X})^{-1}\) 接近奇异,系数估计的 方差暴增 ,某个 \(\beta\) 可能从大正数翻到大负数,t 全部不显著。
诊断工具 —— 方差膨胀因子 VIF :
其中 \(R_j^2\) 是把 \(X_j\) 用其他 \(X\) 回归得到的 \(R^2\)。 经验阈值:VIF \(> 10\) 报警,\(> 5\) 就该关注。 也可以直接看相关矩阵,\(|r| > 0.8\) 是危险信号。
修正方案:删冗余变量、做主成分(PCA)、用岭回归(§8.7)。
陷阱:F 显著 + 每个 t 都不显著
这是多重共线性的招牌信号——『一群人合起来重要,但你说不清谁更重要』。 别强行解释单个系数,先查 VIF。
8.3.7 范畴变量编码与交互项¶
范畴变量 不能直接进矩阵,需要编码:
- One-hot 编码 :\(k\) 个类别 → \(k-1\) 个 0/1 哑变量(多出来的全 1 会与截距共线,所以扔掉一个做基准)
- 效应编码 :\(-1/0/+1\)(适合 ANOVA 风格分析)
- 目标编码 :用类别均值代替(小心训练集泄漏)
例:颜色 \(\in \{\)红, 绿, 蓝\(\}\) → 设 \(D_1 = \text{红?}, D_2 = \text{绿?}\),蓝色作基准(\(D_1 = D_2 = 0\))。
交互项 处理『A 的效应取决于 B』:
\(\beta_3 \neq 0\) 说明 \(X_1\) 的边际效应不是常数,会随 \(X_2\) 变。 例:教育对收入的拉抬幅度,在大城市远大于小城镇——这就需要 教育 \(\times\) 城市规模 的交互。
8.3.8 房价模型解读¶
回到引言里的房价模型,假设跑出 200 套房的 OLS 结果:
每个系数对应一句人话:
- 控制其他变量, 面积每增 1 平米 → 价格增 300 元
- 学区房比非学区贵 8 千/平
- 每老 1 年 → 跌 1500 元/平
- 三个变量解释了 82% 的房价变异,剩下 18% 留给装修、楼层、朝向、户型……
应用场景
工资模型(学历 + 经验 + 行业)、医疗成本预测(年龄 + 慢病 + 城市)、广告归因(多渠道投入 → 销量)、房地产估值、保险精算——只要决策者想知道『其他条件相同时, 这一项独自值多少钱』,多元回归就是第一站。
8.3.9 statsmodels 跑 OLS 并算 VIF¶
import numpy as np, pandas as pd, statsmodels.api as sm
rng = np.random.default_rng(0)
n = 200
area = rng.uniform(50, 200, n)
school = rng.binomial(1, 0.3, n)
age = rng.uniform(0, 30, n)
price = 5 + 0.3*area + 8*school - 0.15*age + rng.normal(0, 5, n)
df = pd.DataFrame({'area': area, 'school': school, 'age': age, 'price': price})
X = sm.add_constant(df[['area', 'school', 'age']])
model = sm.OLS(df['price'], X).fit()
print(model.summary())
# VIF
from statsmodels.stats.outliers_influence import variance_inflation_factor
for i, name in enumerate(X.columns):
print(f"VIF[{name}] = {variance_inflation_factor(X.values, i):.2f}")
summary() 给出每个 \(\hat{\beta}\) 的估计、SE、t、p,外加整体 F、\(R^2\)、adj-\(R^2\);下面的 VIF 循环能立刻把多重共线性可视化。
你知道吗
『偏回归系数』和『简单回归系数』可以差到符号都翻——这叫 辛普森悖论 (Simpson's paradox) 。 历史上最有名的例子是 1973 年加州大学伯克利分校的研究生录取率:单看『总录取率』男生比女生高,看似性别歧视;按 专业 分组后却发现 女生在大多数专业反而更容易被录取 ,只是她们更倾向申请录取率本身就低的专业。 这是『漏掉重要协变量』在多元回归里付出的代价。
8.3.10 本节小结¶
- 多元 OLS 用矩阵闭式 \(\hat{\beta} = (X^\top X)^{-1} X^\top y\),每个 \(\hat{\beta}_j\) 是『控制其他变量』的偏效应。
- 模型对比看 adj-\(R^2\),整体看 F,单变量看 t;F 显著而 t 集体不显著是共线性的招牌。
- 多重共线性用 VIF 诊断,必要时删变量、做 PCA 或转 Ridge(§8.7)。
- 范畴变量哑编码、交互项让模型能容纳更复杂关系,但解读会随之变难。
- 下节 §8.4 学习 回归诊断 ,把 BLUE 假设逐条体检。
