6.1 OLS、系数与设计矩阵:线性模型究竟在估计什么
样本差异、区间估计与检验统计量各自提供不同证据,单个 p 值不能替结论盖上“可靠”印章。若要描述多个连续因素怎样与结果共同变化,就需要把它们放进同一份回归设计矩阵。
“资源增加 10%,完成率会提升多少?”回归可以描述条件关联,干预效果却需要适当的研究设计或识别假设。建模前先决定要做预测、关联描述,还是因果估计,再决定放哪些列。
本课目标
- 用设计矩阵写出多元线性模型;
- 解释 OLS 目标与系数的条件含义;
- 正确处理类别、交互和非线性项;
- 区分预测模型、统计推断和因果问题。
1. 线性是对参数线性
多元模型:
矩阵形式:
“线性”指对系数
2. OLS 最小化残差平方和
满秩条件下可写正规方程解,但数值实现通常使用 QR 或 SVD,不显式计算
系数向量唯一要求设计矩阵列满秩。秩亏时,训练行上的拟合值仍可唯一,单个系数却不可识别;求解器返回数字,并不等于这些数字都有可解释的含义。
平方损失让大残差权重更高,因此 OLS 对高影响点敏感。它并不假设
3. 系数是“其他列固定时”的关联
模型:
它不自动表示给同一任务增派一人会造成该变化。任务难度测量不足、资源分配机制和反向因果都可能混杂。因果解释需要设计或额外识别假设。
4. 截距必须在有意义范围内解释
对连续变量中心化可让截距对应平均附近:
下面的合成样本使用 pandas、NumPy 和 statsmodels 0.15,Python 代码按顺序运行。两个数值预测变量都按训练均值中心化,因此参考类别的截距对应这两个数值均值。
import numpy as np
import pandas as pd
rng = np.random.default_rng(42)
training = pd.DataFrame({
"team_size": rng.integers(2, 9, 48),
"resources_used": rng.uniform(10, 50, 48),
"mission_type": np.tile(["survey", "rescue", "remote"], 16),
})
training["duration_minutes"] = (
30 - 2 * training["team_size"] + 0.4 * training["resources_used"]
+ training["mission_type"].map({"survey": 0, "rescue": 2, "remote": 6})
- 0.5 * training["team_size"] * training["mission_type"].eq("rescue")
+ rng.normal(0, 2, len(training))
)
centers = training[["team_size", "resources_used"]].mean()
for name in centers.index:
training[name + "_centered"] = training[name] - centers[name]若用于评估或线上预测,均值只能在训练数据拟合并保存。
5. 类别变量需要参考组或约束
名义类别不应直接编码为 1,2,3,再当作等距数值。带截距的无正则 OLS 模型应省略一个参考类别,或采用其他明确约束,消除全套哑变量的线性依赖。
Intercept:其他数值列为零时 reference type 的预测基线
type_rescue:rescue 与 reference 的条件差异
type_remote:remote 与 reference 的条件差异换参考组不改变拟合值,却改变单个系数解释。报告时列出参考组,不只展示编码列名。
6. 交互表示斜率随条件变化
duration ~ resources + difficulty + resources:difficulty模型:
resources 的边际斜率为
层级原则通常建议有交互就保留对应主效应,即使单个 p 值不显著;模型结构应来自问题,不是逐项删到都显著。
7. 用公式接口明确模型
import statsmodels.formula.api as smf
formula = (
'duration_minutes ~ resources_used_centered + team_size_centered'
' * C(mission_type, Treatment(reference="survey"))'
)
model = smf.ols(formula, data=training, missing="raise").fit()
if np.linalg.matrix_rank(model.model.exog) != model.model.exog.shape[1]:
raise ValueError("The design does not identify every coefficient")
print(model.params)
print(model.nobs, model.model.exog_names)公式接口方便处理类别和交互,但具体编码、参考组、缺失行删除和 robust covariance 选项需检查。summary() 不是自动正确性证书。
这里 * 展开为两个主效应及其交互。类别系数表示中心化 team size 为零时与 survey 的差异,不是所有团队规模下都相同的差异。应核对设计列名和使用行数,预测时未见过的类别也需要明确策略。
8. 衡量样本内平方误差相对基线
带截距、无正则的嵌套 OLS 模型若使用同一批行和同一个目标,增加列不会提高最小训练 SSE,普通训练
from sklearn.metrics import r2_score
y_test = np.array([10., 12.])
predicted = np.array([10., 10.])
training_mean = 0.0
print(r2_score(y_test, predicted)) # -1.0
print(np.sum((y_test - predicted) ** 2)) # 4.0
print(np.sum((y_test - training_mean) ** 2)) # 244.0这个刻意发生均值偏移的例子中,
9. 结果类型可能不适合 OLS
若每行结果是二分类成功/失败,OLS 线性概率模型可能预测小于 0 或大于 1,并有结构性异方差;logistic 回归通常更贴合概率边界。
若目标是聚合 success_rate,不同分母导致方差不同,需要权重或二项模型。计数、正值长尾和删失时间也各有更合适的模型族。
OLS 仍可作为简单基线或在明确条件下用于比例,但必须诊断和说明局限,不能因为 API 熟悉就默认使用。
常见误区
- 系数是一个变量对结果的因果影响:观测回归默认只有条件关联。
- 线性模型不能表达弯曲关系:可加入基函数,仍对参数线性。
- 高
表示模型正确:泄漏和错设也能得到高值。 - 输出是 0–1 就直接回归 rate:分母与分布模型需要处理。
练习
- 为任务时长模型写出每个系数的“其他列固定”解释。
- 更换类别参考组,验证拟合值不变而系数改变。
- 加入资源与难度交互,写出不同难度下的资源斜率。
- 构造一个高
但由时间泄漏造成的模型。
小结
OLS 通过最小化平方残差估计条件均值结构。设计矩阵决定系数含义,类别、交互和变换决定模型能表达什么;预测、关联与因果则是三种不同目标。
下一课检查模型错在何处:非线性、异方差、相关误差、高杠杆点和共线性会以不同方式影响预测与推断。